From 08ab7ffd08c8dc898b4697bdf57f39ce4f4b8a84 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 1 Feb 2022 18:02:28 +0900 Subject: [PATCH 001/233] Add activitystreams 0.7 to plume-common dependencies --- plume-common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index 25d776cf..befe7d3c 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -24,6 +24,7 @@ tokio = "0.1.22" regex-syntax = { version = "0.6.17", default-features = false, features = ["unicode-perl"] } tracing = "0.1.34" askama_escape = "0.10.3" +activitystreams = "0.7.0-alpha.18" [dependencies.chrono] features = ["serde"] From be1c22815bec2404601f1a595ca578e7962c0382 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 1 Feb 2022 18:06:57 +0900 Subject: [PATCH 002/233] Install activitystreams 0.7 --- Cargo.lock | 851 +++++++++++++++++++++++++++++------------------------ 1 file changed, 472 insertions(+), 379 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee05133b..6eba6fa7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,20 @@ dependencies = [ "serde_json", ] +[[package]] +name = "activitystreams" +version = "0.7.0-alpha.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459a89e7d449cf49e57044d59dcf637d2927362b7a75737c90bd3679ba476a78" +dependencies = [ + "activitystreams-kinds", + "iri-string", + "mime 0.3.16", + "serde 1.0.136", + "serde_json", + "time 0.3.9", +] + [[package]] name = "activitystreams-derive" version = "0.1.1" @@ -27,6 +41,16 @@ dependencies = [ "syn 0.13.11", ] +[[package]] +name = "activitystreams-kinds" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d014a4fb8828870b7b46bee6257b9a89d06188ae8d435381ba94f14c8c697d8" +dependencies = [ + "iri-string", + "serde 1.0.136", +] + [[package]] name = "activitystreams-traits" version = "0.1.0" @@ -55,9 +79,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.15.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ "gimli", ] @@ -137,16 +161,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.4", + "getrandom 0.2.6", "once_cell", "version_check 0.9.4", ] [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -215,13 +239,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.52" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -261,15 +285,18 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" @@ -288,15 +315,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.59" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4717cfcbfaa661a0fd48f8453951837ae7e8f81e481fbb136e3202d72805a744" +checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide", + "miniz_oxide 0.4.4", "object", "rustc-demangle", ] @@ -350,7 +377,7 @@ checksum = "6fe4fef31efb0f76133ae8e3576a88e58edb7cfc5584c81c758c349ba46b43fc" dependencies = [ "base64 0.13.0", "blowfish", - "getrandom 0.2.4", + "getrandom 0.2.6", "zeroize", ] @@ -462,9 +489,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "census" @@ -506,7 +533,7 @@ dependencies = [ "num-integer", "num-traits 0.2.14", "serde 1.0.136", - "time 0.1.43", + "time 0.1.44", "winapi 0.3.9", ] @@ -574,7 +601,7 @@ dependencies = [ "serde 1.0.136", "serde-hjson", "serde_json", - "toml 0.5.8", + "toml 0.5.9", "yaml-rust", ] @@ -604,7 +631,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40" dependencies = [ - "getrandom 0.2.4", + "getrandom 0.2.6", "lazy_static", "proc-macro-hack 0.5.19", "tiny-keccak", @@ -630,9 +657,9 @@ dependencies = [ "hkdf", "hmac", "percent-encoding 2.1.0", - "rand 0.8.4", + "rand 0.8.5", "sha2", - "time 0.1.43", + "time 0.1.44", ] [[package]] @@ -641,7 +668,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" dependencies = [ - "time 0.1.43", + "time 0.1.44", "url 1.7.2", ] @@ -654,20 +681,20 @@ dependencies = [ "cookie 0.12.0", "failure", "idna 0.1.5", - "log 0.4.14", + "log 0.4.16", "publicsuffix", "serde 1.0.136", "serde_json", - "time 0.1.43", + "time 0.1.44", "try_from", "url 1.7.2", ] [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -681,9 +708,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -696,9 +723,9 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" [[package]] name = "crc32fast" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if 1.0.0", ] @@ -724,11 +751,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" dependencies = [ "cfg-if 1.0.0", - "crossbeam-channel 0.5.2", + "crossbeam-channel 0.5.4", "crossbeam-deque 0.8.1", - "crossbeam-epoch 0.9.6", - "crossbeam-queue 0.3.3", - "crossbeam-utils 0.8.6", + "crossbeam-epoch 0.9.8", + "crossbeam-queue 0.3.5", + "crossbeam-utils 0.8.8", ] [[package]] @@ -743,12 +770,12 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.6", + "crossbeam-utils 0.8.8", ] [[package]] @@ -769,8 +796,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ "cfg-if 1.0.0", - "crossbeam-epoch 0.9.6", - "crossbeam-utils 0.8.6", + "crossbeam-epoch 0.9.8", + "crossbeam-utils 0.8.8", ] [[package]] @@ -779,7 +806,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "cfg-if 0.1.10", "crossbeam-utils 0.7.2", "lazy_static", @@ -790,12 +817,13 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.6" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ + "autocfg 1.1.0", "cfg-if 1.0.0", - "crossbeam-utils 0.8.6", + "crossbeam-utils 0.8.8", "lazy_static", "memoffset 0.6.5", "scopeguard", @@ -814,12 +842,12 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b979d76c9fcb84dffc80a73f7290da0f83e4c95773494674cb44b76d13a7a110" +checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.6", + "crossbeam-utils 0.8.8", ] [[package]] @@ -828,16 +856,16 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "cfg-if 0.1.10", "lazy_static", ] [[package]] name = "crossbeam-utils" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if 1.0.0", "lazy_static", @@ -912,10 +940,10 @@ checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.36", - "quote 1.0.15", + "proc-macro2 1.0.37", + "quote 1.0.18", "strsim 0.10.0", - "syn 1.0.86", + "syn 1.0.91", ] [[package]] @@ -925,8 +953,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" dependencies = [ "darling_core", - "quote 1.0.15", - "syn 1.0.86", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -987,9 +1015,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5" dependencies = [ "darling", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -999,7 +1027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73" dependencies = [ "derive_builder_core", - "syn 1.0.86", + "syn 1.0.91", ] [[package]] @@ -1067,9 +1095,9 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -1141,7 +1169,7 @@ dependencies = [ "encoding", "lazy_static", "rand 0.4.6", - "time 0.1.43", + "time 0.1.44", "version_check 0.1.5", ] @@ -1211,9 +1239,9 @@ checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if 1.0.0", ] @@ -1225,7 +1253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be3c61c59fdc91f5dbc3ea31ee8623122ce80057058be560654c5d410d181a6" dependencies = [ "lazy_static", - "log 0.4.14", + "log 0.4.16", "rand 0.7.3", ] @@ -1235,7 +1263,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" dependencies = [ - "backtrace 0.3.59", + "backtrace 0.3.64", "failure_derive", ] @@ -1245,9 +1273,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", "synstructure", ] @@ -1262,35 +1290,35 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] [[package]] name = "filetime" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.10", + "redox_syscall 0.2.13", "winapi 0.3.9", ] [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" dependencies = [ "cfg-if 1.0.0", "crc32fast", "libc", - "miniz_oxide", + "miniz_oxide 0.5.1", ] [[package]] @@ -1377,9 +1405,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ "mac", "new_debug_unreachable", @@ -1393,9 +1421,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -1408,9 +1436,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -1418,9 +1446,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-cpupool" @@ -1434,9 +1462,9 @@ dependencies = [ [[package]] name = "futures-executor" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -1446,38 +1474,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-macro" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -1514,13 +1542,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.10.0+wasi-snapshot-preview1", ] [[package]] @@ -1541,9 +1569,9 @@ checksum = "649db3b5cda06091ea6aacb9f66f7002dfe885505b324b8ed795261253ffc2b3" dependencies = [ "gettext", "gettext-utils", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -1564,9 +1592,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.24.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" [[package]] name = "glob" @@ -1599,7 +1627,7 @@ dependencies = [ "chomp", "guid", "guid-parser", - "rand 0.8.4", + "rand 0.8.5", "winapi 0.3.9", ] @@ -1638,7 +1666,7 @@ dependencies = [ "futures 0.1.31", "http 0.1.21", "indexmap", - "log 0.4.14", + "log 0.4.16", "slab", "string", "tokio-io", @@ -1671,7 +1699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf" dependencies = [ "ahash 0.3.8", - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -1740,12 +1768,12 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" dependencies = [ - "log 0.4.14", + "log 0.4.16", "mac", "markup5ever", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -1800,9 +1828,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.5.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" [[package]] name = "httpdate" @@ -1822,7 +1850,7 @@ dependencies = [ "log 0.3.9", "mime 0.2.6", "num_cpus", - "time 0.1.43", + "time 0.1.44", "traitobject", "typeable", "unicase 1.4.2", @@ -1844,10 +1872,10 @@ dependencies = [ "httparse", "iovec", "itoa 0.4.8", - "log 0.4.14", + "log 0.4.16", "net2", "rustc_version", - "time 0.1.43", + "time 0.1.44", "tokio 0.1.22", "tokio-buf", "tokio-executor", @@ -1945,11 +1973,11 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "hashbrown 0.11.2", ] @@ -1975,9 +2003,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ "generic-array", ] @@ -2002,9 +2030,18 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + +[[package]] +name = "iri-string" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501b97c1eeafd6081c7e46ed862248c161ad29f7e3a5898c893762b25fbaf266" +dependencies = [ + "serde 1.0.136", +] [[package]] name = "itertools" @@ -2092,11 +2129,11 @@ checksum = "9f9aca8b1335c19de45abe198f4142ecd62c2929402c38297a608b09a5299e76" dependencies = [ "async-trait", "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "futures-util", "lazy_static", "lber", - "log 0.4.14", + "log 0.4.16", "maplit", "native-tls", "nom 2.2.1", @@ -2105,7 +2142,7 @@ dependencies = [ "tokio 1.17.0", "tokio-native-tls", "tokio-stream", - "tokio-util 0.7.0", + "tokio-util 0.7.1", "url 2.2.2", ] @@ -2119,7 +2156,7 @@ dependencies = [ "bufstream", "fast_chemail", "hostname", - "log 0.4.14", + "log 0.4.16", "native-tls", "nom 4.2.3", "serde 1.0.136", @@ -2137,7 +2174,7 @@ dependencies = [ "email", "lettre", "mime 0.3.16", - "time 0.1.43", + "time 0.1.44", "uuid 0.7.4", ] @@ -2162,9 +2199,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.119" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" [[package]] name = "libsqlite3-sys" @@ -2295,10 +2332,11 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] @@ -2308,14 +2346,14 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" dependencies = [ - "log 0.4.14", + "log 0.4.16", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if 1.0.0", ] @@ -2347,7 +2385,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ - "log 0.4.14", + "log 0.4.16", "phf", "phf_codegen", "string_cache", @@ -2375,9 +2413,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memmap" @@ -2395,7 +2433,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2404,7 +2442,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2423,9 +2461,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" dependencies = [ "migrations_internals", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -2445,9 +2483,9 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mime_guess" -version = "2.0.3" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" dependencies = [ "mime 0.3.16", "unicase 2.6.0", @@ -2466,7 +2504,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", - "autocfg 1.0.1", + "autocfg 1.1.0", +] + +[[package]] +name = "miniz_oxide" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +dependencies = [ + "adler", ] [[package]] @@ -2481,7 +2528,7 @@ dependencies = [ "iovec", "kernel32-sys", "libc", - "log 0.4.14", + "log 0.4.16", "miow 0.2.2", "net2", "slab", @@ -2490,14 +2537,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ "libc", - "log 0.4.14", + "log 0.4.16", "miow 0.3.7", "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", "winapi 0.3.9", ] @@ -2508,7 +2556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ "lazycell", - "log 0.4.14", + "log 0.4.16", "mio 0.6.23", "slab", ] @@ -2519,7 +2567,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ - "log 0.4.14", + "log 0.4.16", "mio 0.6.23", "miow 0.3.7", "winapi 0.3.9", @@ -2565,11 +2613,11 @@ checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" dependencies = [ "buf_redux", "httparse", - "log 0.4.14", + "log 0.4.16", "mime 0.3.16", "mime_guess", "quick-error", - "rand 0.8.4", + "rand 0.8.5", "safemem", "tempfile", "twoway", @@ -2592,7 +2640,7 @@ checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ "lazy_static", "libc", - "log 0.4.14", + "log 0.4.16", "openssl", "openssl-probe", "openssl-sys", @@ -2680,13 +2728,12 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", - "version_check 0.9.4", ] [[package]] @@ -2697,7 +2744,7 @@ checksum = "37794436ca3029a3089e0b95d42da1f0b565ad271e4d3bb4bad0c7bb70b10605" dependencies = [ "bytecount", "memchr", - "nom 7.1.0", + "nom 7.1.1", ] [[package]] @@ -2720,9 +2767,9 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" dependencies = [ "winapi 0.3.9", ] @@ -2733,7 +2780,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-integer", "num-traits 0.2.14", ] @@ -2744,7 +2791,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-traits 0.2.14", ] @@ -2754,7 +2801,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-integer", "num-traits 0.2.14", ] @@ -2774,7 +2821,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2788,10 +2835,22 @@ dependencies = [ ] [[package]] -name = "object" -version = "0.24.0" +name = "num_threads" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170" +checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +dependencies = [ + "memchr", +] [[package]] name = "once_cell" @@ -2853,7 +2912,7 @@ version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "cc", "libc", "pkg-config", @@ -2896,10 +2955,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.5", + "lock_api 0.4.7", "parking_lot_core 0.8.5", ] +[[package]] +name = "parking_lot" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +dependencies = [ + "lock_api 0.4.7", + "parking_lot_core 0.9.2", +] + [[package]] name = "parking_lot_core" version = "0.6.2" @@ -2924,11 +2993,24 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.10", + "redox_syscall 0.2.13", "smallvec 1.8.0", "winapi 0.3.9", ] +[[package]] +name = "parking_lot_core" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.13", + "smallvec 1.8.0", + "windows-sys", +] + [[package]] name = "pear" version = "0.1.4" @@ -2969,7 +3051,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_shared 0.10.0", + "phf_shared", ] [[package]] @@ -2978,18 +3060,8 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", + "phf_generator", + "phf_shared", ] [[package]] @@ -2998,17 +3070,8 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.4", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", + "phf_shared", + "rand 0.8.5", ] [[package]] @@ -3035,9 +3098,9 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -3060,9 +3123,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plist" @@ -3074,7 +3137,7 @@ dependencies = [ "indexmap", "line-wrap", "serde 1.0.136", - "time 0.3.5", + "time 0.3.9", "xml-rs", ] @@ -3140,6 +3203,7 @@ name = "plume-common" version = "0.7.1" dependencies = [ "activitypub", + "activitystreams", "activitystreams-derive", "activitystreams-traits", "array_tool", @@ -3271,9 +3335,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", "version_check 0.9.4", ] @@ -3283,8 +3347,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", + "proc-macro2 1.0.37", + "quote 1.0.18", "version_check 0.9.4", ] @@ -3338,9 +3402,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid 0.2.2", ] @@ -3410,11 +3474,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ - "proc-macro2 1.0.36", + "proc-macro2 1.0.37", ] [[package]] @@ -3423,7 +3487,7 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" dependencies = [ - "log 0.4.14", + "log 0.4.16", "parking_lot 0.11.2", "scheduled-thread-pool", ] @@ -3447,7 +3511,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" dependencies = [ - "autocfg 0.1.7", + "autocfg 0.1.8", "libc", "rand_chacha 0.1.1", "rand_core 0.4.2", @@ -3455,7 +3519,7 @@ dependencies = [ "rand_isaac", "rand_jitter", "rand_os", - "rand_pcg 0.1.2", + "rand_pcg", "rand_xorshift", "winapi 0.3.9", ] @@ -3471,19 +3535,17 @@ dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", - "rand_pcg 0.2.1", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", "rand_core 0.6.3", - "rand_hc 0.3.1", ] [[package]] @@ -3492,7 +3554,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" dependencies = [ - "autocfg 0.1.7", + "autocfg 0.1.8", "rand_core 0.3.1", ] @@ -3546,7 +3608,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.4", + "getrandom 0.2.6", ] [[package]] @@ -3567,15 +3629,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - [[package]] name = "rand_isaac" version = "0.1.1" @@ -3616,19 +3669,10 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" dependencies = [ - "autocfg 0.1.7", + "autocfg 0.1.8", "rand_core 0.4.2", ] -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "rand_xorshift" version = "0.1.1" @@ -3640,11 +3684,11 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "crossbeam-deque 0.8.1", "either 1.6.1", "rayon-core", @@ -3652,14 +3696,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" dependencies = [ - "crossbeam-channel 0.5.2", + "crossbeam-channel 0.5.4", "crossbeam-deque 0.8.1", - "crossbeam-utils 0.8.6", - "lazy_static", + "crossbeam-utils 0.8.8", "num_cpus", ] @@ -3680,18 +3723,18 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.4.6" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", @@ -3735,7 +3778,7 @@ dependencies = [ "http 0.1.21", "hyper 0.12.36", "hyper-tls 0.3.2", - "log 0.4.14", + "log 0.4.16", "mime 0.3.16", "mime_guess", "native-tls", @@ -3743,7 +3786,7 @@ dependencies = [ "serde_json", "serde_urlencoded 0.5.5", "socks", - "time 0.1.43", + "time 0.1.44", "tokio 0.1.22", "tokio-executor", "tokio-io", @@ -3772,14 +3815,14 @@ dependencies = [ "ipnet", "js-sys", "lazy_static", - "log 0.4.14", + "log 0.4.16", "mime 0.3.16", "mime_guess", "native-tls", "percent-encoding 2.1.0", "pin-project-lite 0.2.8", "serde 1.0.136", - "serde_urlencoded 0.7.0", + "serde_urlencoded 0.7.1", "tokio 0.2.25", "tokio-tls", "url 2.2.2", @@ -3798,7 +3841,7 @@ dependencies = [ "chrono", "config", "dashmap", - "futures 0.3.19", + "futures 0.3.21", "num_cpus", "pin-utils", "rand 0.7.3", @@ -3841,14 +3884,14 @@ checksum = "4a7ab1dfdc75bb8bd2be381f37796b1b300c45a3c9145b34d86715e8dd90bf28" dependencies = [ "atty", "base64 0.13.0", - "log 0.4.14", + "log 0.4.16", "memchr", "num_cpus", "pear", "rocket_codegen", "rocket_http", "state", - "time 0.1.43", + "time 0.1.44", "toml 0.4.10", "version_check 0.9.4", "yansi", @@ -3875,7 +3918,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b6303dccab46dce6c7ac26c9b9d8d8cde1b19614b027c3f913be6611bff6d9b" dependencies = [ - "log 0.4.14", + "log 0.4.16", "notify", "rocket", "serde 1.0.136", @@ -3891,7 +3934,7 @@ dependencies = [ "ring", "rocket", "serde 1.0.136", - "time 0.1.43", + "time 0.1.44", ] [[package]] @@ -3907,7 +3950,7 @@ dependencies = [ "percent-encoding 1.0.1", "smallvec 1.8.0", "state", - "time 0.1.43", + "time 0.1.44", "unicode-xid 0.1.0", ] @@ -3941,7 +3984,7 @@ checksum = "d74a71f39f2d0e35ada983c76aeaa3a58b6c5735c8865073a87d190219c64eb1" dependencies = [ "fastrand", "lazy_static", - "nom 7.1.0", + "nom 7.1.1", "nom_locate", "num-bigint", "num-integer", @@ -3959,7 +4002,7 @@ dependencies = [ "bytecount", "itertools 0.10.3", "md5", - "nom 7.1.0", + "nom 7.1.1", ] [[package]] @@ -4041,9 +4084,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "2.4.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -4054,9 +4097,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ "core-foundation-sys", "libc", @@ -4111,9 +4154,9 @@ version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -4150,12 +4193,12 @@ dependencies = [ [[package]] name = "serde_urlencoded" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 0.4.8", + "itoa 1.0.1", "ryu", "serde 1.0.136", ] @@ -4190,9 +4233,9 @@ checksum = "e63e6744142336dfb606fe2b068afa2e1cca1ee6a5d8377277a92945d81fa331" dependencies = [ "bitflags 1.3.2", "itertools 0.8.2", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -4206,15 +4249,15 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.7" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "slog" @@ -4235,11 +4278,11 @@ dependencies = [ [[package]] name = "slog-stdlog" -version = "4.1.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8228ab7302adbf4fcb37e66f3cda78003feb521e7fd9e3847ec117a7784d0f5a" +checksum = "6706b2ace5bbae7291d3f8d2473e2bfab073ccd7d03670946197aec98471fa3e" dependencies = [ - "log 0.4.14", + "log 0.4.16", "slog", "slog-scope", ] @@ -4288,14 +4331,13 @@ dependencies = [ [[package]] name = "socks" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f86c7635fadf2814201a4f67efefb0007588ae7422ce299f354ab5c97f61ae" +checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" dependencies = [ "byteorder", "libc", - "winapi 0.2.8", - "ws2_32-sys", + "winapi 0.3.9", ] [[package]] @@ -4327,28 +4369,28 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6" +checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" dependencies = [ - "lazy_static", "new_debug_unreachable", - "parking_lot 0.11.2", - "phf_shared 0.8.0", + "once_cell", + "parking_lot 0.12.0", + "phf_shared", "precomputed-hash", "serde 1.0.136", ] [[package]] name = "string_cache_codegen" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", - "proc-macro2 1.0.36", - "quote 1.0.15", + "phf_generator", + "phf_shared", + "proc-macro2 1.0.37", + "quote 1.0.18", ] [[package]] @@ -4415,12 +4457,12 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.86" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", + "proc-macro2 1.0.37", + "quote 1.0.18", "unicode-xid 0.2.2", ] @@ -4430,9 +4472,9 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", "unicode-xid 0.2.2", ] @@ -4477,10 +4519,10 @@ dependencies = [ "failure", "fnv", "fs2", - "futures 0.3.19", + "futures 0.3.21", "htmlescape", "levenshtein_automata", - "log 0.4.14", + "log 0.4.16", "memmap", "murmurhash32", "notify", @@ -4520,10 +4562,10 @@ dependencies = [ "fail", "fnv", "fs2", - "futures 0.3.19", + "futures 0.3.21", "htmlescape", "levenshtein_automata", - "log 0.4.14", + "log 0.4.16", "lru", "memmap", "murmurhash32", @@ -4604,16 +4646,16 @@ dependencies = [ "cfg-if 1.0.0", "fastrand", "libc", - "redox_syscall 0.2.10", + "redox_syscall 0.2.13", "remove_dir_all", "winapi 0.3.9", ] [[package]] name = "tendril" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" dependencies = [ "futf", "mac", @@ -4644,9 +4686,9 @@ version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -4660,22 +4702,24 @@ dependencies = [ [[package]] name = "time" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi 0.3.9", ] [[package]] name = "time" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" dependencies = [ - "itoa 0.4.8", + "itoa 1.0.1", "libc", + "num_threads", ] [[package]] @@ -4759,7 +4803,7 @@ dependencies = [ "bytes 1.1.0", "libc", "memchr", - "mio 0.8.0", + "mio 0.8.2", "pin-project-lite 0.2.8", "socket2 0.4.4", "tokio-macros 1.7.0", @@ -4827,7 +4871,7 @@ checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes 0.4.12", "futures 0.1.31", - "log 0.4.14", + "log 0.4.16", ] [[package]] @@ -4836,9 +4880,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -4847,9 +4891,9 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] @@ -4871,7 +4915,7 @@ dependencies = [ "crossbeam-utils 0.7.2", "futures 0.1.31", "lazy_static", - "log 0.4.14", + "log 0.4.16", "mio 0.6.23", "num_cpus", "parking_lot 0.9.0", @@ -4927,7 +4971,7 @@ dependencies = [ "crossbeam-utils 0.7.2", "futures 0.1.31", "lazy_static", - "log 0.4.14", + "log 0.4.16", "num_cpus", "slab", "tokio-executor", @@ -4963,7 +5007,7 @@ checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" dependencies = [ "bytes 0.4.12", "futures 0.1.31", - "log 0.4.14", + "log 0.4.16", "mio 0.6.23", "tokio-codec", "tokio-io", @@ -4980,7 +5024,7 @@ dependencies = [ "futures 0.1.31", "iovec", "libc", - "log 0.4.14", + "log 0.4.16", "mio 0.6.23", "mio-uds", "tokio-codec", @@ -4997,23 +5041,23 @@ dependencies = [ "bytes 0.5.6", "futures-core", "futures-sink", - "log 0.4.14", + "log 0.4.16", "pin-project-lite 0.1.12", "tokio 0.2.25", ] [[package]] name = "tokio-util" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64910e1b9c1901aaf5375561e35b9c057d95ff41a44ede043a03e09279eabaf1" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" dependencies = [ "bytes 1.1.0", "futures-core", "futures-sink", - "log 0.4.14", "pin-project-lite 0.2.8", "tokio 1.17.0", + "tracing", ] [[package]] @@ -5027,9 +5071,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde 1.0.136", ] @@ -5047,7 +5091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if 1.0.0", - "log 0.4.14", + "log 0.4.16", "pin-project-lite 0.2.8", "tracing-attributes", "tracing-core", @@ -5059,16 +5103,16 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", ] [[package]] name = "tracing-core" -version = "0.1.22" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" dependencies = [ "lazy_static", "valuable", @@ -5091,15 +5135,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" dependencies = [ "lazy_static", - "log 0.4.14", + "log 0.4.16", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9df98b037d039d03400d9dd06b0f8ce05486b5f25e9a2d7d36196e142ebbc52" +checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" dependencies = [ "ansi_term", "sharded-slab", @@ -5249,9 +5293,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8-ranges" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" [[package]] name = "uuid" @@ -5268,7 +5312,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.4", + "getrandom 0.2.6", "serde 1.0.136", ] @@ -5298,10 +5342,10 @@ dependencies = [ "if_chain", "lazy_static", "proc-macro-error", - "proc-macro2 1.0.36", - "quote 1.0.15", + "proc-macro2 1.0.37", + "quote 1.0.18", "regex", - "syn 1.0.86", + "syn 1.0.91", "validator_types", ] @@ -5311,8 +5355,8 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded9d97e1d42327632f5f3bae6403c04886e2de3036261ef42deebd931a6a291" dependencies = [ - "proc-macro2 1.0.36", - "syn 1.0.86", + "proc-macro2 1.0.37", + "syn 1.0.91", ] [[package]] @@ -5369,7 +5413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ "futures 0.1.31", - "log 0.4.14", + "log 0.4.16", "try-lock", ] @@ -5379,7 +5423,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.14", + "log 0.4.16", "try-lock", ] @@ -5391,9 +5435,15 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" @@ -5415,18 +5465,18 @@ checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static", - "log 0.4.14", - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "log 0.4.16", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -5440,7 +5490,7 @@ version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ - "quote 1.0.15", + "quote 1.0.18", "wasm-bindgen-macro-support", ] @@ -5450,9 +5500,9 @@ version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.15", - "syn 1.0.86", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.91", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5536,6 +5586,49 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + [[package]] name = "winreg" version = "0.6.2" @@ -5605,9 +5698,9 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zeroize" From bff50f8e4cfe054e80c79e1f9683c68a0def4180 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 1 Feb 2022 20:20:53 +0900 Subject: [PATCH 003/233] Add activitystreams 0.7 to plume-models dependencies --- plume-models/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-models/Cargo.toml b/plume-models/Cargo.toml index 17b47964..50749b95 100644 --- a/plume-models/Cargo.toml +++ b/plume-models/Cargo.toml @@ -35,6 +35,7 @@ riker = "0.4.2" once_cell = "1.10.0" lettre = "0.9.6" native-tls = "0.2.10" +activitystreams = "0.7.0-alpha.18" [dependencies.chrono] features = ["serde"] From 816aefe72a365152f73756b34836ba246a53871a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 2 Feb 2022 00:17:09 +0900 Subject: [PATCH 004/233] Add ActivityStreams Ext to plume-common dependencies --- plume-common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index befe7d3c..88889988 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -25,6 +25,7 @@ regex-syntax = { version = "0.6.17", default-features = false, features = ["unic tracing = "0.1.34" askama_escape = "0.10.3" activitystreams = "0.7.0-alpha.18" +activitystreams-ext = "0.1.0-alpha.2" [dependencies.chrono] features = ["serde"] From 27c10e5e5cb0db3d24d4611e02b2edda3f66b1fb Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 5 Feb 2022 15:49:16 +0900 Subject: [PATCH 005/233] Install activitystreams-ext --- Cargo.lock | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 6eba6fa7..281af121 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,17 @@ dependencies = [ "syn 0.13.11", ] +[[package]] +name = "activitystreams-ext" +version = "0.1.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8e19a0810cc25df3535061a08b7d8f8a734d309ea4411c57a9767e4a2ffa0e" +dependencies = [ + "activitystreams", + "serde 1.0.136", + "serde_json", +] + [[package]] name = "activitystreams-kinds" version = "0.2.1" @@ -3205,6 +3216,7 @@ dependencies = [ "activitypub", "activitystreams", "activitystreams-derive", + "activitystreams-ext", "activitystreams-traits", "array_tool", "askama_escape", From 3ded0e21661b44eab302d8280af54b33ce192d00 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 5 Feb 2022 18:06:17 +0900 Subject: [PATCH 006/233] Add assert-json-diff to plume-common's dependencies --- plume-common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index 88889988..aadd464a 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -38,5 +38,6 @@ branch = "bidi-plume" [dev-dependencies] once_cell = "1.10.0" +assert-json-diff = "2.0.1" [features] From bc72a4c2d110b7184cea59c0fec9ba4524ec9ae5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 5 Feb 2022 18:18:54 +0900 Subject: [PATCH 007/233] Install assert-json-diff --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 281af121..d7b79fe7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3220,6 +3220,7 @@ dependencies = [ "activitystreams-traits", "array_tool", "askama_escape", + "assert-json-diff", "base64 0.13.0", "chrono", "heck", From 29439f9d027af15569609537f6809ce9fe926c69 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 5 Feb 2022 18:20:09 +0900 Subject: [PATCH 008/233] Add tests for newly added ActivityPub-related structs --- plume-common/src/activity_pub/mod.rs | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 23b2b5f4..5fac258f 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -261,3 +261,94 @@ pub struct Licensed { } impl Object for Licensed {} + +#[cfg(test)] +mod tests { + use super::*; + use assert_json_diff::assert_json_eq; + use serde_json::{from_str, json, to_value}; + + #[test] + fn se_ap_signature() { + let ap_signature = ApSignature07 { + public_key: PublicKey07 { + id: "https://example.com/pubkey".parse().unwrap(), + owner: "https://example.com/owner".parse().unwrap(), + public_key_pem: "pubKeyPem".into(), + }, + }; + let expected = json!({ + "publicKey": { + "id": "https://example.com/pubkey", + "owner": "https://example.com/owner", + "publicKeyPem": "pubKeyPem" + } + }); + assert_json_eq!(to_value(ap_signature).unwrap(), expected); + } + + #[test] + fn de_ap_signature() { + let value: ApSignature07 = from_str( + r#" + { + "publicKey": { + "id": "https://example.com/", + "owner": "https://example.com/", + "publicKeyPem": "" + } + } + "#, + ) + .unwrap(); + let expected = ApSignature07 { + public_key: PublicKey07 { + id: "https://example.com/".parse().unwrap(), + owner: "https://example.com/".parse().unwrap(), + public_key_pem: "".into(), + }, + }; + assert_eq!(value, expected); + } + + #[test] + fn se_custom_person() { + let actor = ApActor::new("https://example.com/inbox".parse().unwrap(), Person::new()); + let person = CustomPerson::new( + actor, + ApSignature07 { + public_key: PublicKey07 { + id: "https://example.com/pubkey".parse().unwrap(), + owner: "https://example.com/owner".parse().unwrap(), + public_key_pem: "pubKeyPem".into(), + }, + }, + ); + let expected = json!({ + "inbox": "https://example.com/inbox", + "type": "Person", + "publicKey": { + "id": "https://example.com/pubkey", + "owner": "https://example.com/owner", + "publicKeyPem": "pubKeyPem" + } + }); + assert_eq!(to_value(person).unwrap(), expected); + } + + #[test] + fn se_licensed_article() { + let object = ApObject::new(Article::new()); + let licensed_article = LicensedArticle::new( + object, + Licensed07 { + license: "CC-0".into(), + }, + ); + let expected = json!({ + "type": "Article", + "license": "CC-0" + }); + assert_json_eq!(to_value(licensed_article).unwrap(), expected); + } +} From 52967f3e476dec1887a11286cf49c254f8efbbe9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 5 Feb 2022 18:20:56 +0900 Subject: [PATCH 009/233] [plume-common]Implement ActivityPub-related code using activitystreams 0.7 --- plume-common/src/activity_pub/mod.rs | 145 +++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 5fac258f..ea7850af 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,4 +1,12 @@ use activitypub::{Activity, Link, Object}; +use activitystreams::{ + activity::AsActivity, + actor::{ApActor, Group, Person}, + iri_string::types::IriString, + object::{ApObject, Article}, + unparsed::UnparsedMutExt, +}; +use activitystreams_ext::{Ext1, UnparsedExtension}; use array_tool::vec::Uniq; use reqwest::{header::HeaderValue, r#async::ClientBuilder, Url}; use rocket::{ @@ -185,6 +193,82 @@ where rt.run().unwrap(); } +pub fn broadcast07(sender: &S, act: A, to: Vec, proxy: Option) +where + S: sign::Signer, + A: AsActivity + serde::Serialize, + T: inbox::AsActor, +{ + let boxes = to + .into_iter() + .map(|u| { + u.get_shared_inbox_url() + .unwrap_or_else(|| u.get_inbox_url()) + }) + .collect::>() + .unique(); + + let mut act = serde_json::to_value(act).expect("activity_pub::broadcast: serialization error"); + act["@context"] = context(); + let signed = act + .sign(sender) + .expect("activity_pub::broadcast: signature error"); + + let mut rt = tokio::runtime::current_thread::Runtime::new() + .expect("Error while initializing tokio runtime for federation"); + for inbox in boxes { + let body = signed.to_string(); + let mut headers = request::headers(); + let url = Url::parse(&inbox); + if url.is_err() { + warn!("Inbox is invalid URL: {:?}", &inbox); + continue; + } + let url = url.unwrap(); + if !url.has_host() { + warn!("Inbox doesn't have host: {:?}", &inbox); + continue; + }; + let host_header_value = HeaderValue::from_str(url.host_str().expect("Unreachable")); + if host_header_value.is_err() { + warn!("Header value is invalid: {:?}", url.host_str()); + continue; + } + headers.insert("Host", host_header_value.unwrap()); + headers.insert("Digest", request::Digest::digest(&body)); + rt.spawn( + if let Some(proxy) = proxy.clone() { + ClientBuilder::new().proxy(proxy) + } else { + ClientBuilder::new() + } + .connect_timeout(std::time::Duration::from_secs(5)) + .build() + .expect("Can't build client") + .post(&inbox) + .headers(headers.clone()) + .header( + "Signature", + request::signature(sender, &headers, ("post", url.path(), url.query())) + .expect("activity_pub::broadcast: request signature error"), + ) + .body(body) + .send() + .and_then(move |r| { + if r.status().is_success() { + debug!("Successfully sent activity to inbox ({})", &inbox); + } else { + warn!("Error while sending to inbox ({:?})", &r) + } + r.into_body().concat2() + }) + .map(move |response| debug!("Response: \"{:?}\"\n", response)) + .map_err(|e| warn!("Error while sending to inbox ({:?})", e)), + ); + } + rt.run().unwrap(); +} + #[derive(Shrinkwrap, Clone, Serialize, Deserialize)] pub struct Id(String); @@ -226,6 +310,41 @@ pub struct PublicKey { pub public_key_pem: Option, } +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ApSignature07 { + public_key: PublicKey07, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct PublicKey07 { + id: IriString, + owner: IriString, + public_key_pem: String, +} + +impl UnparsedExtension for ApSignature07 +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result { + Ok(ApSignature07 { + 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(()) + } +} + +pub type CustomPerson = Ext1, ApSignature07>; +pub type CustomGroup = Ext1, ApSignature07>; + #[derive(Clone, Debug, Default, UnitString)] #[activitystreams(Hashtag)] pub struct HashtagType; @@ -262,6 +381,32 @@ pub struct Licensed { impl Object for Licensed {} +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Licensed07 { + pub license: String, +} + +impl UnparsedExtension for Licensed07 +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result { + Ok(Licensed07 { + license: unparsed_mut.remove("license")?, + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert("license", self.license)?; + Ok(()) + } +} + +pub type LicensedArticle = Ext1, Licensed07>; + #[cfg(test)] mod tests { use super::*; From a21d66178eeee65f5a09ccc37a81e422e0ac965b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 11 Feb 2022 02:18:54 +0900 Subject: [PATCH 010/233] [plume-common]Implement ActivityPub related function using activitystreams 0.7 --- plume-common/src/activity_pub/inbox.rs | 284 +++++++++++++++++++++++++ 1 file changed, 284 insertions(+) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 48ba6c5f..86ea85e5 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -274,6 +274,84 @@ where } } + /// Registers an handler on this Inbox. + pub fn with07(self, proxy: Option<&reqwest::Proxy>) -> Self + where + A: AsActor<&'a C> + FromId07, + V: activitystreams::markers::Activity + serde::de::DeserializeOwned, + M: AsObject07 + FromId07, + M::Output: Into, + { + if let Self::NotHandled(ctx, mut act, e) = self { + if serde_json::from_value::(act.clone()).is_ok() { + let act_clone = act.clone(); + let act_id = match act_clone["id"].as_str() { + Some(x) => x, + None => return Self::NotHandled(ctx, act, InboxError::InvalidID), + }; + + // Get the actor ID + let actor_id = match get_id(act["actor"].clone()) { + Some(x) => x, + None => return Self::NotHandled(ctx, act, InboxError::InvalidActor(None)), + }; + + if Self::is_spoofed_activity(&actor_id, &act) { + return Self::NotHandled(ctx, act, InboxError::InvalidObject(None)); + } + + // Transform this actor to a model (see FromId for details about the from_id function) + let actor = match A::from_id( + ctx, + &actor_id, + serde_json::from_value(act["actor"].clone()).ok(), + proxy, + ) { + Ok(a) => a, + // If the actor was not found, go to the next handler + Err((json, e)) => { + if let Some(json) = json { + act["actor"] = json; + } + return Self::NotHandled(ctx, act, InboxError::InvalidActor(Some(e))); + } + }; + + // Same logic for "object" + let obj_id = match get_id(act["object"].clone()) { + Some(x) => x, + None => return Self::NotHandled(ctx, act, InboxError::InvalidObject(None)), + }; + let obj = match M::from_id( + ctx, + &obj_id, + serde_json::from_value(act["object"].clone()).ok(), + proxy, + ) { + Ok(o) => o, + Err((json, e)) => { + if let Some(json) = json { + act["object"] = json; + } + return Self::NotHandled(ctx, act, InboxError::InvalidObject(Some(e))); + } + }; + + // Handle the activity + match obj.activity(ctx, actor, act_id) { + Ok(res) => Self::Handled(res.into()), + Err(e) => Self::Failed(e), + } + } else { + // If the Activity type is not matching the expected one for + // this handler, try with the next one. + Self::NotHandled(ctx, act, e) + } + } else { + self + } + } + /// Transforms the inbox in a `Result` pub fn done(self) -> Result { match self { @@ -384,6 +462,72 @@ pub trait FromId: Sized { fn get_sender() -> &'static dyn Signer; } +/// A trait for ActivityPub objects that can be retrieved or constructed from ID. +/// +/// The two functions to implement are `from_activity` to create (and save) a new object +/// of this type from its AP representation, and `from_db` to try to find it in the database +/// using its ID. +/// +/// When dealing with the "object" field of incoming activities, `Inbox` will try to see if it is +/// a full object, and if so, save it with `from_activity`. If it is only an ID, it will try to find +/// it in the database with `from_db`, and otherwise dereference (fetch) the full object and parse it +/// with `from_activity`. +pub trait FromId07: Sized { + /// The type representing a failure + type Error: From> + Debug; + + /// The ActivityPub object type representing Self + type Object: activitystreams::markers::Object + serde::de::DeserializeOwned; + + /// Tries to get an instance of `Self` from an ActivityPub ID. + /// + /// # Parameters + /// + /// - `ctx`: a context to get this instance (= a database in which to search) + /// - `id`: the ActivityPub ID of the object to find + /// - `object`: optional object that will be used if the object was not found in the database + /// If absent, the ID will be dereferenced. + fn from_id( + ctx: &C, + id: &str, + object: Option, + proxy: Option<&reqwest::Proxy>, + ) -> Result, Self::Error)> { + match Self::from_db(ctx, id) { + Ok(x) => Ok(x), + _ => match object { + Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)), + None => Self::from_activity(ctx, Self::deref(id, proxy.cloned())?) + .map_err(|e| (None, e)), + }, + } + } + + /// Dereferences an ID + fn deref( + id: &str, + proxy: Option, + ) -> Result, Self::Error)> { + request::get(id, Self::get_sender(), proxy) + .map_err(|_| (None, InboxError::DerefError)) + .and_then(|mut r| { + let json: serde_json::Value = r + .json() + .map_err(|_| (None, InboxError::InvalidObject(None)))?; + serde_json::from_value(json.clone()) + .map_err(|_| (Some(json), InboxError::InvalidObject(None))) + }) + .map_err(|(json, e)| (json, e.into())) + } + + /// Builds a `Self` from its ActivityPub representation + fn from_activity(ctx: &C, activity: Self::Object) -> Result; + + /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) + fn from_db(ctx: &C, id: &str) -> Result; + + fn get_sender() -> &'static dyn Signer; +} /// Should be implemented by anything representing an ActivityPub actor. /// @@ -543,6 +687,146 @@ where fn activity(self, ctx: C, actor: A, id: &str) -> Result; } +/// Should be implemented by anything representing an ActivityPub object. +/// +/// # Type parameters +/// +/// - `A`: the actor type +/// - `V`: the ActivityPub verb/activity +/// - `O`: the ActivityPub type of the Object for this activity (usually the type corresponding to `Self`) +/// - `C`: the context needed to handle the activity (usually a database connection) +/// +/// # Example +/// +/// An implementation of AsObject that handles Note creation by an Account model, +/// representing the Note by a Message type, without any specific context. +/// +/// ```rust +/// # extern crate activitypub; +/// # use activitypub::{activity::Create, actor::Person, object::Note}; +/// # use plume_common::activity_pub::inbox::{AsActor, AsObject, FromId}; +/// # use plume_common::activity_pub::sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}; +/// # use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa}; +/// # use once_cell::sync::Lazy; +/// # +/// # static MY_SIGNER: Lazy = Lazy::new(|| MySigner::new()); +/// # +/// # struct MySigner { +/// # public_key: String, +/// # private_key: String, +/// # } +/// # +/// # impl MySigner { +/// # fn new() -> Self { +/// # let (pub_key, priv_key) = gen_keypair(); +/// # Self { +/// # public_key: String::from_utf8(pub_key).unwrap(), +/// # private_key: String::from_utf8(priv_key).unwrap(), +/// # } +/// # } +/// # } +/// # +/// # impl Signer for MySigner { +/// # fn get_key_id(&self) -> String { +/// # "mysigner".into() +/// # } +/// # +/// # fn sign(&self, to_sign: &str) -> SignResult> { +/// # let key = PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.as_ref()).unwrap()) +/// # .unwrap(); +/// # let mut signer = openssl::sign::Signer::new(MessageDigest::sha256(), &key).unwrap(); +/// # signer.update(to_sign.as_bytes()).unwrap(); +/// # signer.sign_to_vec().map_err(|_| SignError()) +/// # } +/// # +/// # fn verify(&self, data: &str, signature: &[u8]) -> SignResult { +/// # let key = PKey::from_rsa(Rsa::public_key_from_pem(self.public_key.as_ref()).unwrap()) +/// # .unwrap(); +/// # let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha256(), &key).unwrap(); +/// # verifier.update(data.as_bytes()).unwrap(); +/// # verifier.verify(&signature).map_err(|_| SignError()) +/// # } +/// # } +/// # +/// # struct Account; +/// # impl FromId<()> for Account { +/// # type Error = (); +/// # type Object = Person; +/// # +/// # fn from_db(_: &(), _id: &str) -> Result { +/// # Ok(Account) +/// # } +/// # +/// # fn from_activity(_: &(), obj: Person) -> Result { +/// # Ok(Account) +/// # } +/// # +/// # fn get_sender() -> &'static dyn Signer { +/// # &*MY_SIGNER +/// # } +/// # } +/// # impl AsActor<()> for Account { +/// # fn get_inbox_url(&self) -> String { +/// # String::new() +/// # } +/// # fn is_local(&self) -> bool { false } +/// # } +/// #[derive(Debug)] +/// struct Message { +/// text: String, +/// } +/// +/// impl FromId<()> for Message { +/// type Error = (); +/// type Object = Note; +/// +/// fn from_db(_: &(), _id: &str) -> Result { +/// Ok(Message { text: "From DB".into() }) +/// } +/// +/// fn from_activity(_: &(), obj: Note) -> Result { +/// Ok(Message { text: obj.object_props.content_string().map_err(|_| ())? }) +/// } +/// +/// fn get_sender() -> &'static dyn Signer { +/// &*MY_SIGNER +/// } +/// } +/// +/// impl AsObject for Message { +/// type Error = (); +/// type Output = (); +/// +/// fn activity(self, _: (), _actor: Account, _id: &str) -> Result<(), ()> { +/// println!("New Note: {:?}", self); +/// Ok(()) +/// } +/// } +/// ``` +pub trait AsObject07 +where + V: activitystreams::markers::Activity, +{ + /// What kind of error is returned when something fails + type Error; + + /// What is returned by `AsObject::activity`, if anything is returned + type Output = (); + + /// Handle a specific type of activity dealing with this type of objects. + /// + /// The implementations should check that the actor is actually authorized + /// to perform this action. + /// + /// # Parameters + /// + /// - `self`: the object on which the activity acts + /// - `ctx`: the context passed to `Inbox::handle` + /// - `actor`: the actor who did this activity + /// - `id`: the ID of this activity + fn activity(self, ctx: C, actor: A, id: &str) -> Result; +} + #[cfg(test)] mod tests { use super::*; From 119d3e4f6a4defbe21de8fb446ef72f171d1b8fa Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 11 Feb 2022 02:29:29 +0900 Subject: [PATCH 011/233] [plume-common]Add tests for new ActivityPub functions --- plume-common/src/activity_pub/inbox.rs | 175 +++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 86ea85e5..3a7eb5d8 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -834,6 +834,15 @@ mod tests { gen_keypair, Error as SignError, Result as SignResult, Signer, }; use activitypub::{activity::*, actor::Person, object::Note}; + use activitystreams::{ + activity::{ + Announce as Announce07, Create as Create07, Delete as Delete07, Like as Like07, + }, + actor::Person as Person07, + base::Base, + object::Note as Note07, + prelude::*, + }; use once_cell::sync::Lazy; use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa}; @@ -893,6 +902,22 @@ mod tests { &*MY_SIGNER } } + impl FromId07<()> for MyActor { + type Error = (); + type Object = Person07; + + fn from_db(_: &(), _id: &str) -> Result { + Ok(Self) + } + + fn from_activity(_: &(), _obj: Person07) -> Result { + Ok(Self) + } + + fn get_sender() -> &'static dyn Signer { + &*MY_SIGNER + } + } impl AsActor<&()> for MyActor { fn get_inbox_url(&self) -> String { @@ -961,6 +986,63 @@ mod tests { } } + struct MyObject07; + impl FromId07<()> for MyObject07 { + type Error = (); + type Object = Note07; + + fn from_db(_: &(), _id: &str) -> Result { + Ok(Self) + } + + fn from_activity(_: &(), _obj: Note07) -> Result { + Ok(Self) + } + + fn get_sender() -> &'static dyn Signer { + &*MY_SIGNER + } + } + impl AsObject07 for MyObject07 { + type Error = (); + type Output = (); + + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + println!("MyActor is creating a Note"); + Ok(()) + } + } + + impl AsObject07 for MyObject07 { + type Error = (); + type Output = (); + + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + println!("MyActor is liking a Note"); + Ok(()) + } + } + + impl AsObject07 for MyObject07 { + type Error = (); + type Output = (); + + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + println!("MyActor is deleting a Note"); + Ok(()) + } + } + + impl AsObject07 for MyObject07 { + type Error = (); + type Output = (); + + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + println!("MyActor is announcing a Note"); + Ok(()) + } + } + fn build_create() -> Create { let mut act = Create::default(); act.object_props @@ -980,6 +1062,19 @@ mod tests { act } + fn build_create07() -> Create07 { + let mut person = Person07::new(); + person.set_id("https://test.ap/actor".parse().unwrap()); + let mut note = Note07::new(); + note.set_id("https://test.ap/note".parse().unwrap()); + let mut act = Create07::new( + Base::retract(person).unwrap().into_generic().unwrap(), + Base::retract(note).unwrap().into_generic().unwrap(), + ); + act.set_id("https://test.ap/activity".parse().unwrap()); + act + } + #[test] fn test_inbox_basic() { let act = serde_json::to_value(build_create()).unwrap(); @@ -989,6 +1084,15 @@ mod tests { assert!(res.is_ok()); } + #[test] + fn test_inbox_basic07() { + let act = serde_json::to_value(build_create07()).unwrap(); + let res: Result<(), ()> = Inbox::handle(&(), act) + .with07::(None) + .done(); + assert!(res.is_ok()); + } + #[test] fn test_inbox_multi_handlers() { let act = serde_json::to_value(build_create()).unwrap(); @@ -1001,6 +1105,18 @@ mod tests { assert!(res.is_ok()); } + #[test] + fn test_inbox_multi_handlers07() { + let act = serde_json::to_value(build_create()).unwrap(); + let res: Result<(), ()> = Inbox::handle(&(), act) + .with07::(None) + .with07::(None) + .with07::(None) + .with07::(None) + .done(); + assert!(res.is_ok()); + } + #[test] fn test_inbox_failure() { let act = serde_json::to_value(build_create()).unwrap(); @@ -1012,6 +1128,17 @@ mod tests { assert!(res.is_err()); } + #[test] + fn test_inbox_failure07() { + let act = serde_json::to_value(build_create07()).unwrap(); + // Create is not handled by this inbox + let res: Result<(), ()> = Inbox::handle(&(), act) + .with07::(None) + .with07::(None) + .done(); + assert!(res.is_err()); + } + struct FailingActor; impl FromId<()> for FailingActor { type Error = (); @@ -1054,6 +1181,38 @@ mod tests { } } + impl FromId07<()> for FailingActor { + type Error = (); + type Object = Person07; + + fn from_db(_: &(), _id: &str) -> Result { + Err(()) + } + + fn from_activity(_: &(), _obj: Self::Object) -> Result { + Err(()) + } + + fn get_sender() -> &'static dyn Signer { + &*MY_SIGNER + } + } + + impl AsObject07 for MyObject07 { + type Error = (); + type Output = (); + + fn activity( + self, + _: &(), + _actor: FailingActor, + _id: &str, + ) -> Result { + println!("FailingActor is creating a Note"); + Ok(()) + } + } + #[test] fn test_inbox_actor_failure() { let act = serde_json::to_value(build_create()).unwrap(); @@ -1069,4 +1228,20 @@ mod tests { .done(); assert!(res.is_ok()); } + + #[test] + fn test_inbox_actor_failure07() { + let act = serde_json::to_value(build_create07()).unwrap(); + + let res: Result<(), ()> = Inbox::handle(&(), act.clone()) + .with07::(None) + .done(); + assert!(res.is_err()); + + let res: Result<(), ()> = Inbox::handle(&(), act.clone()) + .with07::(None) + .with07::(None) + .done(); + assert!(res.is_ok()); + } } From 3e687f3af0782011b67d5dbfb24db26c6caa34f2 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 11 Feb 2022 12:55:52 +0900 Subject: [PATCH 012/233] Reduce type parameter from broadcast07 --- plume-common/src/activity_pub/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index ea7850af..f3b33607 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,8 +1,8 @@ use activitypub::{Activity, Link, Object}; use activitystreams::{ - activity::AsActivity, actor::{ApActor, Group, Person}, iri_string::types::IriString, + markers::Activity as Activity07, object::{ApObject, Article}, unparsed::UnparsedMutExt, }; @@ -196,7 +196,7 @@ where pub fn broadcast07(sender: &S, act: A, to: Vec, proxy: Option) where S: sign::Signer, - A: AsActivity + serde::Serialize, + A: Activity07 + serde::Serialize, T: inbox::AsActor, { let boxes = to From 4b3b5c1f403ab0bada3073aa34b62ae5a295bbe4 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 11 Feb 2022 14:20:04 +0900 Subject: [PATCH 013/233] Implement From for Error --- plume-models/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plume-models/src/lib.rs b/plume-models/src/lib.rs index 546d5997..18afde57 100644 --- a/plume-models/src/lib.rs +++ b/plume-models/src/lib.rs @@ -127,6 +127,12 @@ impl From for Error { } } +impl From for Error { + fn from(_: activitystreams::checked::CheckError) -> Error { + Error::MissingApProperty + } +} + impl From for Error { fn from(_: webfinger::WebfingerError) -> Self { Error::Webfinger From 66f5628a279cf76f06cfe056875e9940f6df4b5e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 11 Feb 2022 14:35:47 +0900 Subject: [PATCH 014/233] Add suffix 07 to activitystreams 0.7 related methods --- plume-common/src/activity_pub/inbox.rs | 74 ++++++++++++++++---------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 3a7eb5d8..5bcf5ed9 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -301,7 +301,7 @@ where } // Transform this actor to a model (see FromId for details about the from_id function) - let actor = match A::from_id( + let actor = match A::from_id07( ctx, &actor_id, serde_json::from_value(act["actor"].clone()).ok(), @@ -322,7 +322,7 @@ where Some(x) => x, None => return Self::NotHandled(ctx, act, InboxError::InvalidObject(None)), }; - let obj = match M::from_id( + let obj = match M::from_id07( ctx, &obj_id, serde_json::from_value(act["object"].clone()).ok(), @@ -338,7 +338,7 @@ where }; // Handle the activity - match obj.activity(ctx, actor, act_id) { + match obj.activity07(ctx, actor, act_id) { Ok(res) => Self::Handled(res.into()), Err(e) => Self::Failed(e), } @@ -487,28 +487,28 @@ pub trait FromId07: Sized { /// - `id`: the ActivityPub ID of the object to find /// - `object`: optional object that will be used if the object was not found in the database /// If absent, the ID will be dereferenced. - fn from_id( + fn from_id07( ctx: &C, id: &str, object: Option, proxy: Option<&reqwest::Proxy>, ) -> Result, Self::Error)> { - match Self::from_db(ctx, id) { + match Self::from_db07(ctx, id) { Ok(x) => Ok(x), _ => match object { - Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)), - None => Self::from_activity(ctx, Self::deref(id, proxy.cloned())?) + Some(o) => Self::from_activity07(ctx, o).map_err(|e| (None, e)), + None => Self::from_activity07(ctx, Self::deref07(id, proxy.cloned())?) .map_err(|e| (None, e)), }, } } /// Dereferences an ID - fn deref( + fn deref07( id: &str, proxy: Option, ) -> Result, Self::Error)> { - request::get(id, Self::get_sender(), proxy) + request::get(id, Self::get_sender07(), proxy) .map_err(|_| (None, InboxError::DerefError)) .and_then(|mut r| { let json: serde_json::Value = r @@ -521,12 +521,12 @@ pub trait FromId07: Sized { } /// Builds a `Self` from its ActivityPub representation - fn from_activity(ctx: &C, activity: Self::Object) -> Result; + fn from_activity07(ctx: &C, activity: Self::Object) -> Result; /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) - fn from_db(ctx: &C, id: &str) -> Result; + fn from_db07(ctx: &C, id: &str) -> Result; - fn get_sender() -> &'static dyn Signer; + fn get_sender07() -> &'static dyn Signer; } /// Should be implemented by anything representing an ActivityPub actor. @@ -824,7 +824,7 @@ where /// - `ctx`: the context passed to `Inbox::handle` /// - `actor`: the actor who did this activity /// - `id`: the ID of this activity - fn activity(self, ctx: C, actor: A, id: &str) -> Result; + fn activity07(self, ctx: C, actor: A, id: &str) -> Result; } #[cfg(test)] @@ -906,15 +906,15 @@ mod tests { type Error = (); type Object = Person07; - fn from_db(_: &(), _id: &str) -> Result { + fn from_db07(_: &(), _id: &str) -> Result { Ok(Self) } - fn from_activity(_: &(), _obj: Person07) -> Result { + fn from_activity07(_: &(), _obj: Person07) -> Result { Ok(Self) } - fn get_sender() -> &'static dyn Signer { + fn get_sender07() -> &'static dyn Signer { &*MY_SIGNER } } @@ -991,15 +991,15 @@ mod tests { type Error = (); type Object = Note07; - fn from_db(_: &(), _id: &str) -> Result { + fn from_db07(_: &(), _id: &str) -> Result { Ok(Self) } - fn from_activity(_: &(), _obj: Note07) -> Result { + fn from_activity07(_: &(), _obj: Note07) -> Result { Ok(Self) } - fn get_sender() -> &'static dyn Signer { + fn get_sender07() -> &'static dyn Signer { &*MY_SIGNER } } @@ -1007,7 +1007,12 @@ mod tests { type Error = (); type Output = (); - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + fn activity07( + self, + _: &(), + _actor: MyActor, + _id: &str, + ) -> Result { println!("MyActor is creating a Note"); Ok(()) } @@ -1017,7 +1022,12 @@ mod tests { type Error = (); type Output = (); - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + fn activity07( + self, + _: &(), + _actor: MyActor, + _id: &str, + ) -> Result { println!("MyActor is liking a Note"); Ok(()) } @@ -1027,7 +1037,12 @@ mod tests { type Error = (); type Output = (); - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + fn activity07( + self, + _: &(), + _actor: MyActor, + _id: &str, + ) -> Result { println!("MyActor is deleting a Note"); Ok(()) } @@ -1037,7 +1052,12 @@ mod tests { type Error = (); type Output = (); - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { + fn activity07( + self, + _: &(), + _actor: MyActor, + _id: &str, + ) -> Result { println!("MyActor is announcing a Note"); Ok(()) } @@ -1185,15 +1205,15 @@ mod tests { type Error = (); type Object = Person07; - fn from_db(_: &(), _id: &str) -> Result { + fn from_db07(_: &(), _id: &str) -> Result { Err(()) } - fn from_activity(_: &(), _obj: Self::Object) -> Result { + fn from_activity07(_: &(), _obj: Self::Object) -> Result { Err(()) } - fn get_sender() -> &'static dyn Signer { + fn get_sender07() -> &'static dyn Signer { &*MY_SIGNER } } @@ -1202,7 +1222,7 @@ mod tests { type Error = (); type Output = (); - fn activity( + fn activity07( self, _: &(), _actor: FailingActor, From f3b67ab6c9f7e3986236c2d2198ce07789a55e27 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 11 Feb 2022 14:49:52 +0900 Subject: [PATCH 015/233] WIP --- plume-models/src/users.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 1e27fb19..2100d721 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -11,6 +11,7 @@ use activitypub::{ object::{Image, Tombstone}, Activity, CustomObject, Endpoint, }; +use activitystreams::{actor::ApActor, object::AsApObject, prelude::*}; use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; use ldap3::{LdapConn, Scope, SearchEntry}; @@ -22,10 +23,11 @@ use openssl::{ }; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, - ActivityStream, ApSignature, Id, IntoId, PublicKey, PUBLIC_VISIBILITY, + ActivityStream, ApSignature, CustomPerson as CustomPerson07, Id, IntoId, PublicKey, + PUBLIC_VISIBILITY, }, utils, }; @@ -1025,6 +1027,23 @@ impl FromId for User { } } +impl FromId07 for User { + type Error = Error; + type Object = CustomPerson07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Self::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, acct: CustomPerson07) -> Result { + let url = Url::parse(acct.ap_object_ref().id()?)?; + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsActor<&DbConn> for User { fn get_inbox_url(&self) -> String { self.inbox_url.clone() From a6d839a7663297986010b40d9fb5998a98560f04 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 12 Feb 2022 13:23:44 +0900 Subject: [PATCH 016/233] Make fields of ApSignature07 and PublicKey07 public --- plume-common/src/activity_pub/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index f3b33607..82514cd0 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -313,15 +313,15 @@ pub struct PublicKey { #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ApSignature07 { - public_key: PublicKey07, + pub public_key: PublicKey07, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct PublicKey07 { - id: IriString, - owner: IriString, - public_key_pem: String, + pub id: IriString, + pub owner: IriString, + pub public_key_pem: String, } impl UnparsedExtension for ApSignature07 From e407d58ee9a3bd75f1a3369da2f03c69c16c216d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 12 Feb 2022 22:32:19 +0900 Subject: [PATCH 017/233] Implement FromId07 for User --- plume-models/src/users.rs | 134 +++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 2100d721..53a20ad0 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -11,7 +11,11 @@ use activitypub::{ object::{Image, Tombstone}, Activity, CustomObject, Endpoint, }; -use activitystreams::{actor::ApActor, object::AsApObject, prelude::*}; +use activitystreams::{ + actor::AsApActor, + object::{AsApObject, AsObject as _}, + prelude::*, +}; use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; use ldap3::{LdapConn, Scope, SearchEntry}; @@ -1036,7 +1040,133 @@ impl FromId07 for User { } fn from_activity07(conn: &DbConn, acct: CustomPerson07) -> Result { - let url = Url::parse(acct.ap_object_ref().id()?)?; + let actor = acct.ap_actor_ref(); + let username = actor + .preferred_username() + .ok_or(Error::MissingApProperty)? + .to_string(); + + if username.contains(&['<', '>', '&', '@', '\'', '"', ' ', '\t'][..]) { + return Err(Error::InvalidValue); + } + + let summary = acct + .object_ref() + .summary() + .and_then(|prop| { + if let Some(p) = prop.as_one() { + p.as_xsd_string() + .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) + } else if let Some(ps) = prop.as_many() { + ps.iter().next().and_then(|p| { + p.as_xsd_string() + .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) + }) + } else { + None + } + }) + .unwrap_or_default(); + let mut new_user = NewUser { + display_name: acct + .object_ref() + .name() + .and_then(|prop| { + if let Some(p) = prop.as_one() { + p.as_xsd_string() + .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) + } else if let Some(ps) = prop.as_many() { + ps.iter().next().and_then(|p| { + p.as_xsd_string() + .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) + }) + } else { + None + } + }) + .unwrap_or(&username) + .to_string(), + username: username.to_string(), + outbox_url: actor.outbox()?.ok_or(Error::MissingApProperty)?.to_string(), + inbox_url: actor.inbox()?.to_string(), + role: 2, + summary: summary.to_string(), + summary_html: SafeString::new(summary), + public_key: acct.ext_one.public_key.public_key_pem.to_string(), + shared_inbox_url: actor + .endpoints()? + .and_then(|e| e.shared_inbox.map(|inbox| inbox.to_string())), + followers_endpoint: actor + .followers()? + .ok_or(Error::MissingApProperty)? + .to_string(), + ..NewUser::default() + }; + + let avatar_id = if let Some(icon) = acct.object_ref().icon() { + if let Some(prop) = icon.as_one() { + prop.as_xsd_any_uri().map(|uri| uri.to_string()) + } else if let Some(prop) = icon.as_many() { + prop.iter() + .next() + .and_then(|p| p.as_xsd_any_uri()) + .map(|uri| uri.to_string()) + } else { + None + } + } else { + None + }; + + let (ap_url, inst) = { + let any_base = acct.into_any_base()?; + let id = any_base.id().ok_or(Error::MissingApProperty)?; + ( + id.to_string(), + id.authority_components() + .ok_or(Error::Url)? + .host() + .to_string(), + ) + }; + new_user.ap_url = ap_url; + + let instance = Instance::find_by_domain(conn, &inst).or_else(|_| { + Instance::insert( + conn, + NewInstance { + name: inst.to_owned(), + public_domain: inst.to_owned(), + local: false, + // We don't really care about all the following for remote instances + long_description: SafeString::new(""), + short_description: SafeString::new(""), + default_license: String::new(), + open_registrations: true, + short_description_html: String::new(), + long_description_html: String::new(), + }, + ) + })?; + new_user.instance_id = instance.id; + new_user.fqn = if instance.local { + username.to_string() + } else { + format!("{}@{}", username, instance.public_domain) + }; + + let user = User::insert(conn, new_user)?; + if let Some(avatar_id) = avatar_id { + let avatar = Media::save_remote(conn, avatar_id, &user); + + if let Ok(avatar) = avatar { + if let Err(e) = user.set_avatar(conn, avatar.id) { + tracing::error!("{:?}", e); + } + } + } + + Ok(user) } fn get_sender07() -> &'static dyn Signer { From a80a95d471100151bcda97a996d782f1c8859e52 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 00:52:41 +0900 Subject: [PATCH 018/233] Implement OneOrMany<&AnyString>::to_as_string() --- plume-common/src/activity_pub/mod.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 82514cd0..374ef9bf 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -4,6 +4,7 @@ use activitystreams::{ iri_string::types::IriString, markers::Activity as Activity07, object::{ApObject, Article}, + primitives::{AnyString, OneOrMany}, unparsed::UnparsedMutExt, }; use activitystreams_ext::{Ext1, UnparsedExtension}; @@ -407,6 +408,27 @@ where pub type LicensedArticle = Ext1, Licensed07>; +pub trait ToAsString { + fn to_as_string(&self) -> Option; +} + +impl ToAsString for OneOrMany<&AnyString> { + fn to_as_string(&self) -> Option { + if let Some(prop) = self.as_one() { + prop.as_xsd_string() + .or_else(|| prop.as_rdf_lang_string().map(|ls| ls.value.as_str())) + } else if let Some(props) = self.as_many() { + props.iter().next().and_then(|prop| { + prop.as_xsd_string() + .or_else(|| prop.as_rdf_lang_string().map(|ls| ls.value.as_str())) + }) + } else { + None + } + .map(|s| s.to_string()) + } +} + #[cfg(test)] mod tests { use super::*; From 3db10a09bbf2453ddfe1597ca58b8b865526858b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 00:53:08 +0900 Subject: [PATCH 019/233] Use OneOrMany<&AnyString>::to_as_string() --- plume-models/src/users.rs | 41 ++++++++------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 53a20ad0..6fd0ae21 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -31,7 +31,7 @@ use plume_common::{ request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, CustomPerson as CustomPerson07, Id, IntoId, PublicKey, - PUBLIC_VISIBILITY, + ToAsString, PUBLIC_VISIBILITY, }, utils, }; @@ -1053,45 +1053,20 @@ impl FromId07 for User { let summary = acct .object_ref() .summary() - .and_then(|prop| { - if let Some(p) = prop.as_one() { - p.as_xsd_string() - .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) - } else if let Some(ps) = prop.as_many() { - ps.iter().next().and_then(|p| { - p.as_xsd_string() - .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) - }) - } else { - None - } - }) + .and_then(|prop| prop.to_as_string()) .unwrap_or_default(); let mut new_user = NewUser { display_name: acct .object_ref() .name() - .and_then(|prop| { - if let Some(p) = prop.as_one() { - p.as_xsd_string() - .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) - } else if let Some(ps) = prop.as_many() { - ps.iter().next().and_then(|p| { - p.as_xsd_string() - .or_else(|| p.as_rdf_lang_string().map(|ls| ls.value.as_str())) - }) - } else { - None - } - }) - .unwrap_or(&username) - .to_string(), - username: username.to_string(), + .and_then(|prop| prop.to_as_string()) + .unwrap_or_else(|| username.clone()), + username: username.clone(), outbox_url: actor.outbox()?.ok_or(Error::MissingApProperty)?.to_string(), inbox_url: actor.inbox()?.to_string(), role: 2, - summary: summary.to_string(), - summary_html: SafeString::new(summary), + summary_html: SafeString::new(&summary), + summary, public_key: acct.ext_one.public_key.public_key_pem.to_string(), shared_inbox_url: actor .endpoints()? @@ -1150,7 +1125,7 @@ impl FromId07 for User { })?; new_user.instance_id = instance.id; new_user.fqn = if instance.local { - username.to_string() + username } else { format!("{}@{}", username, instance.public_domain) }; From 28643fc2c2832372f53589959f79a014da282634 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 00:59:15 +0900 Subject: [PATCH 020/233] Implement &AnyString::as_as_str() --- plume-common/src/activity_pub/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 374ef9bf..e4fcc655 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -429,6 +429,17 @@ impl ToAsString for OneOrMany<&AnyString> { } } +trait AsAsStr { + fn as_as_str(&self) -> Option<&str>; +} + +impl AsAsStr for &AnyString { + fn as_as_str(&self) -> Option<&str> { + self.as_xsd_string() + .or_else(|| self.as_rdf_lang_string().map(|ls| ls.value.as_str())) + } +} + #[cfg(test)] mod tests { use super::*; From e9258657670142ca2e33b887c89849e98db2fd7a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 00:59:36 +0900 Subject: [PATCH 021/233] Use &AnyString::as_as_str() --- plume-common/src/activity_pub/mod.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index e4fcc655..8a5c9590 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -415,13 +415,9 @@ pub trait ToAsString { impl ToAsString for OneOrMany<&AnyString> { fn to_as_string(&self) -> Option { if let Some(prop) = self.as_one() { - prop.as_xsd_string() - .or_else(|| prop.as_rdf_lang_string().map(|ls| ls.value.as_str())) + prop.as_as_str() } else if let Some(props) = self.as_many() { - props.iter().next().and_then(|prop| { - prop.as_xsd_string() - .or_else(|| prop.as_rdf_lang_string().map(|ls| ls.value.as_str())) - }) + props.iter().next().and_then(|prop| prop.as_as_str()) } else { None } From 249fbbe891d8ec98f119a552fc65a9b5d71fddfc Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:00:24 +0900 Subject: [PATCH 022/233] Remove unused import --- plume-models/src/users.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 6fd0ae21..b18bc037 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -11,11 +11,7 @@ use activitypub::{ object::{Image, Tombstone}, Activity, CustomObject, Endpoint, }; -use activitystreams::{ - actor::AsApActor, - object::{AsApObject, AsObject as _}, - prelude::*, -}; +use activitystreams::{actor::AsApActor, object::AsObject as _, prelude::*}; use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; use ldap3::{LdapConn, Scope, SearchEntry}; From a6a21d5dfa180218f5be35b38e59648ab780e0c7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:05:25 +0900 Subject: [PATCH 023/233] Rewrite to_as_string() using method chain instead of if expressions --- plume-common/src/activity_pub/mod.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 8a5c9590..fc9098b2 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -414,14 +414,13 @@ pub trait ToAsString { impl ToAsString for OneOrMany<&AnyString> { fn to_as_string(&self) -> Option { - if let Some(prop) = self.as_one() { - prop.as_as_str() - } else if let Some(props) = self.as_many() { - props.iter().next().and_then(|prop| prop.as_as_str()) - } else { - None - } - .map(|s| s.to_string()) + self.as_one() + .and_then(|prop| prop.as_as_str()) + .or_else(|| { + self.as_many() + .and_then(|props| props.iter().next().and_then(|prop| prop.as_as_str())) + }) + .map(|s| s.to_string()) } } From f0112850fa94b9c6e3d713403936c68636b3a918 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:15:23 +0900 Subject: [PATCH 024/233] Implement OneOrMany<&AnyString>::as_as_str() --- plume-common/src/activity_pub/mod.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index fc9098b2..f4e681ef 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -435,6 +435,15 @@ impl AsAsStr for &AnyString { } } +impl AsAsStr for OneOrMany<&AnyString> { + fn as_as_str(&self) -> Option<&str> { + self.as_one().and_then(|prop| prop.as_as_str()).or_else(|| { + self.as_many() + .and_then(|props| props.iter().next().and_then(|prop| prop.as_as_str())) + }) + } +} + #[cfg(test)] mod tests { use super::*; From 456df3e5350136a6ad79f41913e05065250e04e1 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:15:39 +0900 Subject: [PATCH 025/233] Use OneOrMany<&AnyString>::as_as_str() --- plume-common/src/activity_pub/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index f4e681ef..cfc589d6 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -414,13 +414,7 @@ pub trait ToAsString { impl ToAsString for OneOrMany<&AnyString> { fn to_as_string(&self) -> Option { - self.as_one() - .and_then(|prop| prop.as_as_str()) - .or_else(|| { - self.as_many() - .and_then(|props| props.iter().next().and_then(|prop| prop.as_as_str())) - }) - .map(|s| s.to_string()) + self.as_as_str().map(|s| s.to_string()) } } From bb5157637d893310e868c73f4fad6d265841d2ff Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:23:36 +0900 Subject: [PATCH 026/233] Implement OneOrMany::to_as_uri() --- plume-common/src/activity_pub/mod.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index cfc589d6..b8853d1b 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,6 +1,7 @@ use activitypub::{Activity, Link, Object}; use activitystreams::{ actor::{ApActor, Group, Person}, + base::AnyBase, iri_string::types::IriString, markers::Activity as Activity07, object::{ApObject, Article}, @@ -438,6 +439,25 @@ impl AsAsStr for OneOrMany<&AnyString> { } } +pub trait ToAsUri { + fn to_as_uri(&self) -> Option; +} + +impl ToAsUri for OneOrMany { + fn to_as_uri(&self) -> Option { + if let Some(prop) = self.as_one() { + prop.as_xsd_any_uri().map(|uri| uri.to_string()) + } else if let Some(prop) = self.as_many() { + prop.iter() + .next() + .and_then(|p| p.as_xsd_any_uri()) + .map(|uri| uri.to_string()) + } else { + None + } + } +} + #[cfg(test)] mod tests { use super::*; From 4ccfec8019bd256a243978c5f85e842101d77ce3 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:23:47 +0900 Subject: [PATCH 027/233] Use OneOrMany::to_as_uri() --- plume-models/src/users.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index b18bc037..5f1152be 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -27,7 +27,7 @@ use plume_common::{ request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, CustomPerson as CustomPerson07, Id, IntoId, PublicKey, - ToAsString, PUBLIC_VISIBILITY, + ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils, }; @@ -1075,16 +1075,7 @@ impl FromId07 for User { }; let avatar_id = if let Some(icon) = acct.object_ref().icon() { - if let Some(prop) = icon.as_one() { - prop.as_xsd_any_uri().map(|uri| uri.to_string()) - } else if let Some(prop) = icon.as_many() { - prop.iter() - .next() - .and_then(|p| p.as_xsd_any_uri()) - .map(|uri| uri.to_string()) - } else { - None - } + icon.to_as_uri() } else { None }; From d3e11c78d7a0904f45a4cbab0f1cc741d43d2c2b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:31:15 +0900 Subject: [PATCH 028/233] [REFACTORING]Use method chain instead of if clauses --- plume-common/src/activity_pub/mod.rs | 20 ++++++++++---------- plume-models/src/users.rs | 6 +----- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index b8853d1b..493980bc 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -445,16 +445,16 @@ pub trait ToAsUri { impl ToAsUri for OneOrMany { fn to_as_uri(&self) -> Option { - if let Some(prop) = self.as_one() { - prop.as_xsd_any_uri().map(|uri| uri.to_string()) - } else if let Some(prop) = self.as_many() { - prop.iter() - .next() - .and_then(|p| p.as_xsd_any_uri()) - .map(|uri| uri.to_string()) - } else { - None - } + self.as_one() + .and_then(|prop| prop.as_xsd_any_uri().map(|uri| uri.to_string())) + .or_else(|| { + self.as_many().and_then(|props| { + props + .iter() + .next() + .and_then(|prop| prop.as_xsd_any_uri().map(|uri| uri.to_string())) + }) + }) } } diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 5f1152be..33c3d2f4 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1074,11 +1074,7 @@ impl FromId07 for User { ..NewUser::default() }; - let avatar_id = if let Some(icon) = acct.object_ref().icon() { - icon.to_as_uri() - } else { - None - }; + let avatar_id = acct.object_ref().icon().and_then(|icon| icon.to_as_uri()); let (ap_url, inst) = { let any_base = acct.into_any_base()?; From c1b9ebdae64d2a6e4f970392254a74b519f76d47 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:33:04 +0900 Subject: [PATCH 029/233] [REFACTORING]Reduce duplicated closure --- plume-common/src/activity_pub/mod.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 493980bc..b7ebae31 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -446,15 +446,12 @@ pub trait ToAsUri { impl ToAsUri for OneOrMany { fn to_as_uri(&self) -> Option { self.as_one() - .and_then(|prop| prop.as_xsd_any_uri().map(|uri| uri.to_string())) + .and_then(|prop| prop.as_xsd_any_uri()) .or_else(|| { - self.as_many().and_then(|props| { - props - .iter() - .next() - .and_then(|prop| prop.as_xsd_any_uri().map(|uri| uri.to_string())) - }) + self.as_many() + .and_then(|props| props.iter().next().and_then(|prop| prop.as_xsd_any_uri())) }) + .map(|uri| uri.to_string()) } } From ab126563f3cb4d05e190814666d0de5c99ee7a3c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 01:43:01 +0900 Subject: [PATCH 030/233] Implement AsObject07 for User --- plume-models/src/users.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 33c3d2f4..ebd44867 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -11,7 +11,9 @@ use activitypub::{ object::{Image, Tombstone}, Activity, CustomObject, Endpoint, }; -use activitystreams::{actor::AsApActor, object::AsObject as _, prelude::*}; +use activitystreams::{ + activity::Delete as Delete07, actor::AsApActor, object::AsObject as _, prelude::*, +}; use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; use ldap3::{LdapConn, Scope, SearchEntry}; @@ -1161,6 +1163,19 @@ impl AsObject for User { } } +impl AsObject07 for User { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + if self.id == actor.id { + self.delete(conn).map(|_| ()) + } else { + Err(Error::Unauthorized) + } + } +} + impl Signer for User { fn get_key_id(&self) -> String { format!("{}#main-key", self.ap_url) From e42aa6fe8e120bbd02697299ea5d076890911b62 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 02:07:23 +0900 Subject: [PATCH 031/233] Implement From for Error --- plume-models/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plume-models/src/lib.rs b/plume-models/src/lib.rs index 18afde57..0720599b 100644 --- a/plume-models/src/lib.rs +++ b/plume-models/src/lib.rs @@ -16,6 +16,7 @@ extern crate serde_json; #[macro_use] extern crate tantivy; +use activitystreams::iri_string; pub use lettre; pub use lettre::smtp; use once_cell::sync::Lazy; @@ -100,6 +101,12 @@ impl From for Error { } } +impl From for Error { + fn from(_: iri_string::validate::Error) -> Self { + Error::Url + } +} + impl From for Error { fn from(_: serde_json::Error) -> Self { Error::SerDe From d62f51665bc46bdc5be5772bef8d33c13b45bbb6 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 02:09:28 +0900 Subject: [PATCH 032/233] Implement User::outbox_collection07() --- plume-models/src/users.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index ebd44867..9b305e54 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -12,7 +12,9 @@ use activitypub::{ Activity, CustomObject, Endpoint, }; use activitystreams::{ - activity::Delete as Delete07, actor::AsApActor, object::AsObject as _, prelude::*, + activity::Delete as Delete07, actor::AsApActor, + collection::OrderedCollection as OrderedCollection07, iri_string::types::IriString, + object::AsObject as _, prelude::*, }; use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; @@ -449,6 +451,19 @@ impl User { .set_total_items_u64(self.get_activities_count(conn) as u64)?; Ok(coll) } + pub fn outbox_collection07(&self, conn: &Connection) -> Result { + let mut coll = OrderedCollection07::new(); + let first = &format!("{}?page=1", &self.outbox_url); + let last = &format!( + "{}?page={}", + &self.outbox_url, + self.get_activities_count(conn) / i64::from(ITEMS_PER_PAGE) + 1 + ); + coll.set_first(first.parse::()?); + coll.set_last(last.parse::()?); + coll.set_total_items(self.get_activities_count(conn) as u64); + Ok(coll) + } pub fn outbox_page( &self, conn: &Connection, From e392a89526a6c42a7d2440fccb63cde49c85e131 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 02:22:17 +0900 Subject: [PATCH 033/233] Add test for User::outbox_collection07() --- plume-models/src/users.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 9b305e54..68b0487a 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1673,6 +1673,27 @@ pub(crate) mod tests { }); } + #[test] + fn outbox_collection07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (_pages, users, _blogs) = fill_pages(&conn); + let user = &users[0]; + let act = user.outbox_collection07(&conn)?; + + let expected = json!({ + "first": "https://plu.me/@/admin/outbox?page=1", + "last": "https://plu.me/@/admin/outbox?page=5", + "totalItems": 51, + "type": "OrderedCollection", + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn outbox_collection_page() { let conn = db(); From 038d65acaa18dfa9494411e2f42e1fe7f87c1c50 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 02:22:48 +0900 Subject: [PATCH 034/233] Implement User::outbox07() --- plume-models/src/users.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 68b0487a..c626a45d 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -437,6 +437,9 @@ impl User { pub fn outbox(&self, conn: &Connection) -> Result> { Ok(ActivityStream::new(self.outbox_collection(conn)?)) } + pub fn outbox07(&self, conn: &Connection) -> Result> { + Ok(ActivityStream::new(self.outbox_collection07(conn)?)) + } pub fn outbox_collection(&self, conn: &Connection) -> Result { let mut coll = OrderedCollection::default(); let first = &format!("{}?page=1", &self.outbox_url); From cb8e2e929400e4e24d9e949e866d37aa8e41a2c1 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 17:41:52 +0900 Subject: [PATCH 035/233] Implement User::to_activity() --- plume-models/src/users.rs | 52 +++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index c626a45d..0d5ef10d 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -12,9 +12,13 @@ use activitypub::{ Activity, CustomObject, Endpoint, }; use activitystreams::{ - activity::Delete as Delete07, actor::AsApActor, - collection::OrderedCollection as OrderedCollection07, iri_string::types::IriString, - object::AsObject as _, prelude::*, + activity::Delete as Delete07, + actor::AsApActor, + actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, + collection::OrderedCollection as OrderedCollection07, + iri_string::types::IriString, + object::{AsObject as _, Image as Image07}, + prelude::*, }; use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; @@ -30,8 +34,8 @@ use plume_common::{ inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, - ActivityStream, ApSignature, CustomPerson as CustomPerson07, Id, IntoId, PublicKey, - ToAsString, ToAsUri, PUBLIC_VISIBILITY, + ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, + PublicKey, PublicKey07, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils, }; @@ -808,6 +812,44 @@ impl User { Ok(CustomPerson::new(actor, ap_signature)) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut actor = ApActor07::new(self.inbox_url.parse()?, Person07::new()); + let ap_url = self.ap_url.parse::()?; + actor.set_id(ap_url.clone()); + actor.set_name(self.display_name.clone()); + actor.set_summary(self.summary_html.get().clone()); + actor.set_url(ap_url.clone()); + actor.set_inbox(self.inbox_url.parse()?); + actor.set_outbox(self.outbox_url.parse()?); + actor.set_preferred_username(self.username.clone()); + actor.set_followers(self.followers_endpoint.parse()?); + + if let Some(shared_inbox_url) = self.shared_inbox_url.clone() { + let endpoints = Endpoints07 { + shared_inbox: Some(shared_inbox_url.parse::()?), + ..Endpoints07::default() + }; + actor.set_endpoints(endpoints); + } + + let pub_key = PublicKey07 { + id: format!("{}#main-key", self.ap_url).parse()?, + owner: ap_url, + public_key_pem: self.public_key.clone(), + }; + let ap_signature = ApSignature07 { + public_key: pub_key, + }; + + if let Some(avatar_id) = self.avatar_id { + let mut avatar = Image07::new(); + avatar.set_url(Media::get(conn, avatar_id)?.url()?.parse::()?); + actor.set_icon(avatar.into_any_base()?); + } + + Ok(CustomPerson07::new(actor, ap_signature)) + } + pub fn delete_activity(&self, conn: &Connection) -> Result { let mut del = Delete::default(); From ad951ca842760f384f3518bc266ea27012b58f35 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 17:57:06 +0900 Subject: [PATCH 036/233] Add test for User::to_activity07() --- plume-models/src/users.rs | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 0d5ef10d..9bbb9776 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1669,6 +1669,67 @@ pub(crate) mod tests { Ok(()) }); } + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let users = fill_database(&conn); + let user = &users[0]; + let act = user.to_activity07(&conn)?; + + let expected = json!({ + "endpoints": { + "sharedInbox": "https://plu.me/inbox" + }, + "followers": "https://plu.me/@/admin/followers", + "id": "https://plu.me/@/admin/", + "inbox": "https://plu.me/@/admin/inbox", + "name": "The admin", + "outbox": "https://plu.me/@/admin/outbox", + "preferredUsername": "admin", + "publicKey": { + "id": "https://plu.me/@/admin/#main-key", + "owner": "https://plu.me/@/admin/", + "publicKeyPem": user.public_key, + }, + "summary": "

Hello there, I’m the admin

\n", + "type": "Person", + "url": "https://plu.me/@/admin/" + }); + + assert_json_eq!(to_value(act)?, expected); + + let other = &users[2]; + let other_act = other.to_activity07(&conn)?; + let expected_other = json!({ + "endpoints": { + "sharedInbox": "https://plu.me/inbox" + }, + "followers": "https://plu.me/@/other/followers", + "icon": { + "url": "https://plu.me/static/media/example.png", + "type": "Image", + }, + "id": "https://plu.me/@/other/", + "inbox": "https://plu.me/@/other/inbox", + "name": "Another user", + "outbox": "https://plu.me/@/other/outbox", + "preferredUsername": "other", + "publicKey": { + "id": "https://plu.me/@/other/#main-key", + "owner": "https://plu.me/@/other/", + "publicKeyPem": other.public_key, + }, + "summary": "

Hello there, I’m someone else

\n", + "type": "Person", + "url": "https://plu.me/@/other/" + }); + + assert_json_eq!(to_value(other_act)?, expected_other); + + Ok(()) + }); + } #[test] fn delete_activity() { From 55ca1345e1a6ae821f355bec3d312ea45c799495 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 17:59:22 +0900 Subject: [PATCH 037/233] Add test self_federation07() for User --- plume-models/src/users.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 9bbb9776..ee290560 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1604,6 +1604,32 @@ pub(crate) mod tests { }); } + #[test] + fn self_federation07() { + let conn = db(); + conn.test_transaction::<_, (), _>(|| { + let users = fill_database(&conn); + + let ap_repr = users[0].to_activity07(&conn).unwrap(); + users[0].delete(&conn).unwrap(); + let user = User::from_activity07(&conn, ap_repr).unwrap(); + + assert_eq!(user.username, users[0].username); + assert_eq!(user.display_name, users[0].display_name); + assert_eq!(user.outbox_url, users[0].outbox_url); + assert_eq!(user.inbox_url, users[0].inbox_url); + assert_eq!(user.instance_id, users[0].instance_id); + assert_eq!(user.ap_url, users[0].ap_url); + assert_eq!(user.public_key, users[0].public_key); + assert_eq!(user.shared_inbox_url, users[0].shared_inbox_url); + assert_eq!(user.followers_endpoint, users[0].followers_endpoint); + assert_eq!(user.avatar_url(&conn), users[0].avatar_url(&conn)); + assert_eq!(user.fqn, users[0].fqn); + assert_eq!(user.summary_html, users[0].summary_html); + Ok(()) + }); + } + #[test] fn to_activity() { let conn = db(); From 8d69051a614af3749da7bab0f7ed986e753de728 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 18:43:14 +0900 Subject: [PATCH 038/233] Implement User::delete_activity07() --- plume-models/src/users.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index ee290560..5e8f79a7 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -17,7 +17,7 @@ use activitystreams::{ actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, collection::OrderedCollection as OrderedCollection07, iri_string::types::IriString, - object::{AsObject as _, Image as Image07}, + object::{AsObject as _, Image as Image07, Tombstone as Tombstone07}, prelude::*, }; use chrono::{NaiveDateTime, Utc}; @@ -873,6 +873,25 @@ impl User { Ok(del) } + pub fn delete_activity07(&self, conn: &Connection) -> Result { + let mut tombstone = Tombstone07::new(); + tombstone.set_id(self.ap_url.parse()?); + + let mut del = Delete07::new( + self.ap_url.parse::()?, + tombstone.into_any_base()?, + ); + del.set_id(format!("{}#delete", self.ap_url).parse()?); + del.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + del.set_many_ccs( + self.get_followers(conn)? + .into_iter() + .filter_map(|f| f.ap_url.parse::().ok()), + ); + + Ok(del) + } + pub fn avatar_url(&self, conn: &Connection) -> String { self.avatar_id .and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok()) From 0979471e542b41889751dae0b1afd63e6e999bcc Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 18:48:16 +0900 Subject: [PATCH 039/233] Add test for User::delete_activity07() --- plume-models/src/users.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 5e8f79a7..b64b451e 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1802,6 +1802,32 @@ pub(crate) mod tests { }); } + #[test] + fn delete_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let users = fill_database(&conn); + let user = &users[1]; + let act = user.delete_activity07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/user/", + "cc": [], + "id": "https://plu.me/@/user/#delete", + "object": { + "id": "https://plu.me/@/user/", + "type": "Tombstone", + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Delete", + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn outbox_collection() { let conn = db(); From e7eea3901fae0af38925cff3388276a429aa274b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 13 Feb 2022 19:09:13 +0900 Subject: [PATCH 040/233] Implement User::outbox_page07() --- plume-models/src/users.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index b64b451e..34b628fe 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -15,7 +15,9 @@ use activitystreams::{ activity::Delete as Delete07, actor::AsApActor, actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, - collection::OrderedCollection as OrderedCollection07, + collection::{ + OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, + }, iri_string::types::IriString, object::{AsObject as _, Image as Image07, Tombstone as Tombstone07}, prelude::*, @@ -480,6 +482,15 @@ impl User { self.outbox_collection_page(conn, (min, max))?, )) } + pub fn outbox_page07( + &self, + conn: &Connection, + (min, max): (i32, i32), + ) -> Result> { + Ok(ActivityStream::new( + self.outbox_collection_page07(conn, (min, max))?, + )) + } pub fn outbox_collection_page( &self, conn: &Connection, From 7f0ad56d079de6abd7867315162eac7afddf3773 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 02:08:28 +0900 Subject: [PATCH 041/233] Implement User::outbox_collection_page07() --- plume-models/src/users.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 34b628fe..ce90bee5 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -15,6 +15,7 @@ use activitystreams::{ activity::Delete as Delete07, actor::AsApActor, actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, + base::AnyBase, collection::{ OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, }, @@ -518,6 +519,33 @@ impl User { .set_part_of_link(Id::new(&self.outbox_url))?; Ok(coll) } + pub fn outbox_collection_page07( + &self, + conn: &Connection, + (min, max): (i32, i32), + ) -> Result { + let acts = self.get_activities_page(conn, (min, max))?; + let n_acts = self.get_activities_count(conn); + let mut coll = OrderedCollectionPage07::new(); + if n_acts - i64::from(min) >= i64::from(ITEMS_PER_PAGE) { + coll.set_next( + format!("{}?page={}", &self.outbox_url, min / ITEMS_PER_PAGE + 2) + .parse::()?, + ); + } + if min > 0 { + coll.set_prev( + format!("{}?page={}", &self.outbox_url, min / ITEMS_PER_PAGE) + .parse::()?, + ); + } + coll.set_many_items( + acts.iter() + .filter_map(|value| AnyBase::from_arbitrary_json(value).ok()), + ); + coll.set_part_of(self.outbox_url.parse::()?); + Ok(coll) + } fn fetch_outbox_page(&self, url: &str) -> Result<(Vec, Option)> { let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; let text = &res.text()?; From 6323c7aef8dc77d412d99c5fe47f9129ec97539e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 02:27:16 +0900 Subject: [PATCH 042/233] Add test for User::outbox_page_collection07() --- plume-models/src/users.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index ce90bee5..70e102c6 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -1930,4 +1930,25 @@ pub(crate) mod tests { Ok(()) }); } + + #[test] + fn outbox_collection_page07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let users = fill_database(&conn); + let user = &users[0]; + let act = user.outbox_collection_page07(&conn, (33, 36))?; + + let expected = json!({ + "items": [], + "partOf": "https://plu.me/@/admin/outbox", + "prev": "https://plu.me/@/admin/outbox?page=2", + "type": "OrderedCollectionPage", + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 78b05350631c7a2d2cb71b6569f9b84251e37243 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 02:38:13 +0900 Subject: [PATCH 043/233] Implement User::fetch_outbox_page07() --- plume-models/src/users.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 70e102c6..04241cd4 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -20,6 +20,7 @@ use activitystreams::{ OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, }, iri_string::types::IriString, + markers::Activity as Activity07, object::{AsObject as _, Image as Image07, Tombstone as Tombstone07}, prelude::*, }; @@ -560,6 +561,23 @@ impl User { let next = json.get("next").map(|x| x.as_str().unwrap().to_owned()); Ok((items, next)) } + pub fn fetch_outbox_page07( + &self, + url: &str, + ) -> Result<(Vec, Option)> { + let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; + let text = &res.text()?; + let json: serde_json::Value = serde_json::from_str(text)?; + let items = json["items"] + .as_array() + .unwrap_or(&vec![]) + .iter() + .filter_map(|j| serde_json::from_value(j.clone()).ok()) + .collect::>(); + + let next = json.get("next").map(|x| x.as_str().unwrap().to_owned()); + Ok((items, next)) + } pub fn fetch_outbox(&self) -> Result> { let mut res = get( &self.outbox_url[..], From 8f4dd8a57b621d2d0b5874d0746522b82bfecafe Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 02:38:22 +0900 Subject: [PATCH 044/233] Implement User::fetch_outbox07() --- plume-models/src/users.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 04241cd4..616b1beb 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -614,6 +614,42 @@ impl User { } } + pub fn fetch_outbox07(&self) -> Result> { + let mut res = get( + &self.outbox_url[..], + Self::get_sender(), + CONFIG.proxy().cloned(), + )?; + let text = &res.text()?; + let json: serde_json::Value = serde_json::from_str(text)?; + if let Some(first) = json.get("first") { + let mut items: Vec = Vec::new(); + let mut next = first.as_str().unwrap().to_owned(); + while let Ok((mut page, nxt)) = self.fetch_outbox_page07(&next) { + if page.is_empty() { + break; + } + items.append(&mut page); + if let Some(n) = nxt { + if n == next { + break; + } + next = n; + } else { + break; + } + } + Ok(items) + } else { + Ok(json["items"] + .as_array() + .unwrap_or(&vec![]) + .iter() + .filter_map(|j| serde_json::from_value(j.clone()).ok()) + .collect::>()) + } + } + pub fn fetch_followers_ids(&self) -> Result> { let mut res = get( &self.followers_endpoint[..], From da9e13622cc548a7a74c49b21a234cb8d52f131c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 03:17:08 +0900 Subject: [PATCH 045/233] Use Inbox::with07() for User, Delete, User --- plume-models/src/inbox.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 21af9d88..8d744407 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -1,4 +1,5 @@ use activitypub::activity::*; +use activitystreams::activity::Delete as Delete07; use crate::{ comments::Comment, @@ -53,7 +54,7 @@ pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) From 85e35fdb5dde2e0e1fc13836ec985fa0af4bb8b6 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 20:14:39 +0900 Subject: [PATCH 046/233] Update activitystreams --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index d7b79fe7..8e0d5d79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3271,6 +3271,7 @@ name = "plume-models" version = "0.7.1" dependencies = [ "activitypub", + "activitystreams", "ammonia", "assert-json-diff", "bcrypt", From 6b5a1d21300b4082537bdf8f8a807969fb6ee54a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 20:21:19 +0900 Subject: [PATCH 047/233] Use Base::retract() instead of into_any_base() on creating activity --- plume-models/src/users.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 616b1beb..638d9620 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -15,7 +15,7 @@ use activitystreams::{ activity::Delete as Delete07, actor::AsApActor, actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, - base::AnyBase, + base::{AnyBase, Base}, collection::{ OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, }, @@ -972,7 +972,7 @@ impl User { let mut del = Delete07::new( self.ap_url.parse::()?, - tombstone.into_any_base()?, + Base::retract(tombstone)?.into_generic()?, ); del.set_id(format!("{}#delete", self.ap_url).parse()?); del.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); From a1a7acfe941ed11fa3968fcd75ff8bced1352142 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 14 Feb 2022 20:44:28 +0900 Subject: [PATCH 048/233] Use new activitystreams APIs --- plume-common/src/activity_pub/mod.rs | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index b7ebae31..2a8e91a6 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -423,19 +423,9 @@ trait AsAsStr { fn as_as_str(&self) -> Option<&str>; } -impl AsAsStr for &AnyString { - fn as_as_str(&self) -> Option<&str> { - self.as_xsd_string() - .or_else(|| self.as_rdf_lang_string().map(|ls| ls.value.as_str())) - } -} - impl AsAsStr for OneOrMany<&AnyString> { fn as_as_str(&self) -> Option<&str> { - self.as_one().and_then(|prop| prop.as_as_str()).or_else(|| { - self.as_many() - .and_then(|props| props.iter().next().and_then(|prop| prop.as_as_str())) - }) + self.iter().next().map(|prop| prop.as_str()) } } @@ -445,13 +435,9 @@ pub trait ToAsUri { impl ToAsUri for OneOrMany { fn to_as_uri(&self) -> Option { - self.as_one() - .and_then(|prop| prop.as_xsd_any_uri()) - .or_else(|| { - self.as_many() - .and_then(|props| props.iter().next().and_then(|prop| prop.as_xsd_any_uri())) - }) - .map(|uri| uri.to_string()) + self.iter() + .next() + .and_then(|prop| prop.as_xsd_any_uri().map(|uri| uri.to_string())) } } From 4edc201c14017572953a3052490a359208a68004 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 00:48:06 +0900 Subject: [PATCH 049/233] Implement FromId07 for Blog --- plume-models/src/blogs.rs | 135 +++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 9d0839ae..a95805da 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -8,6 +8,12 @@ use activitypub::{ object::Image, CustomObject, }; +use activitystreams::{ + actor::AsApActor, + base::AnyBase, + object::{kind::ImageType, ApObject, ApObjectExt, Image as Image07, ObjectExt}, + prelude::*, +}; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SaveChangesDsl}; use openssl::{ @@ -17,8 +23,9 @@ use openssl::{ sign::{Signer, Verifier}, }; use plume_common::activity_pub::{ - inbox::{AsActor, FromId}, - sign, ActivityStream, ApSignature, Id, IntoId, PublicKey, Source, + inbox::{AsActor, FromId, FromId07}, + sign, ActivityStream, ApSignature, CustomGroup as CustomGroup07, Id, IntoId, PublicKey, Source, + ToAsString, ToAsUri, }; use url::Url; use webfinger::*; @@ -449,6 +456,130 @@ impl FromId for Blog { } } +impl FromId07 for Blog { + type Error = Error; + type Object = CustomGroup07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Self::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, acct: CustomGroup07) -> Result { + let (name, outbox_url, inbox_url) = { + let actor = acct.ap_actor_ref(); + let name = actor + .preferred_username() + .ok_or(Error::MissingApProperty)? + .to_string(); + if name.contains(&['<', '>', '&', '@', '\'', '"', ' ', '\t'][..]) { + return Err(Error::InvalidValue); + } + ( + name, + actor.outbox()?.ok_or(Error::MissingApProperty)?.to_string(), + actor.inbox()?.to_string(), + ) + }; + + let mut new_blog = NewBlog { + actor_id: name.to_string(), + outbox_url, + inbox_url, + public_key: acct.ext_one.public_key.public_key_pem.to_string(), + private_key: None, + theme: None, + ..NewBlog::default() + }; + + let object = ApObject::new(acct.inner); + new_blog.title = object + .name() + .and_then(|name| name.to_as_string()) + .unwrap_or_else(|| name); + new_blog.summary_html = SafeString::new( + &object + .summary() + .and_then(|summary| summary.to_as_string()) + .unwrap_or_default(), + ); + + let icon_id = object + .icon() + .and_then(|icons| { + icons.iter().next().and_then(|icon| { + let icon = icon.to_owned().extend::().ok()??; + let owner = icon.attributed_to()?.to_as_uri()?; + Media::save_remote( + conn, + icon.url()?.to_as_uri()?, + &User::from_id07(conn, &owner, None, CONFIG.proxy()).ok()?, + ) + .ok() + }) + }) + .map(|m| m.id); + new_blog.icon_id = icon_id; + + let banner_id = object + .image() + .and_then(|banners| { + banners.iter().next().and_then(|banner| { + let banner = banner.to_owned().extend::().ok()??; + let owner = banner.attributed_to()?.to_as_uri()?; + Media::save_remote( + conn, + banner.url()?.to_as_uri()?, + &User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?, + ) + .ok() + }) + }) + .map(|m| m.id); + new_blog.banner_id = banner_id; + + let source = object + .source() + .and_then(|s| s.as_xsd_string()) + .unwrap_or_default() + .to_string(); + new_blog.summary = source; + + let any_base = AnyBase::from_extended(object)?; + let id = any_base.id().ok_or(Error::MissingApProperty)?; + new_blog.ap_url = id.to_string(); + + let inst = id + .authority_components() + .ok_or(Error::Url)? + .host() + .to_string(); + let instance = Instance::find_by_domain(conn, &inst).or_else(|_| { + Instance::insert( + conn, + NewInstance { + public_domain: inst.to_owned(), + name: inst.to_owned(), + local: false, + // We don't really care about all the following for remote instances + long_description: SafeString::new(""), + short_description: SafeString::new(""), + default_license: String::new(), + open_registrations: true, + short_description_html: String::new(), + long_description_html: String::new(), + }, + ) + })?; + new_blog.instance_id = instance.id; + + Blog::insert(conn, new_blog) + } + + fn get_sender07() -> &'static dyn sign::Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsActor<&PlumeRocket> for Blog { fn get_inbox_url(&self) -> String { self.inbox_url.clone() From ab6f39c19266f4e3c3ba3a2d7ccef0558d4d2e42 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 01:07:57 +0900 Subject: [PATCH 050/233] Add test for Blog::to_activity() --- plume-models/src/blogs.rs | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index a95805da..1f1e7e20 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -643,7 +643,9 @@ pub(crate) mod tests { blog_authors::*, instance::tests as instance_tests, medias::NewMedia, tests::db, users::tests as usersTests, Connection as Conn, }; + use assert_json_diff::assert_json_eq; use diesel::Connection; + use serde_json::to_value; pub(crate) fn fill_database(conn: &Conn) -> (Vec, Vec) { instance_tests::fill_database(conn); @@ -1038,4 +1040,50 @@ pub(crate) mod tests { Ok(()) }) } + + #[test] + fn to_activity() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (_users, blogs) = fill_database(&conn); + let blog = &blogs[0]; + let act = blog.to_activity(conn)?; + + let expected = json!({ + "followers": null, + "following": null, + "icon": { + "attributedTo": "", + "type": "Image", + "url": "" + }, + "id": "https://plu.me/~/BlogName/", + "image": { + "attributedTo": "", + "type": "Image", + "url": "" + }, + "inbox": "https://plu.me/~/BlogName/inbox", + "liked": null, + "name": "Blog name", + "outbox": "https://plu.me/~/BlogName/outbox", + "preferredUsername": "BlogName", + "publicKey": { + "id": "https://plu.me/~/BlogName/#main-key", + "owner": "https://plu.me/~/BlogName/", + "publicKeyPem": blog.public_key + }, + "source": { + "content": "This is a small blog", + "mediaType": "text/markdown" + }, + "summary": "", + "type": "Group" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 00862790a18a344e9d39fb90ad66cf0e42e2abff Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 01:48:19 +0900 Subject: [PATCH 051/233] Extract Blog::outbox_collection() --- plume-models/src/blogs.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 1f1e7e20..33c3586c 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -230,6 +230,10 @@ impl Blog { } pub fn outbox(&self, conn: &Connection) -> Result> { + self.outbox_collection(conn) + .map(|coll| ActivityStream::new(coll)) + } + pub fn outbox_collection(&self, conn: &Connection) -> Result { let mut coll = OrderedCollection::default(); coll.collection_props.items = serde_json::to_value(self.get_activities(conn))?; coll.collection_props @@ -243,7 +247,7 @@ impl Blog { (self.get_activities(conn).len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64 / ITEMS_PER_PAGE as u64 ))))?; - Ok(ActivityStream::new(coll)) + Ok(coll) } pub fn outbox_page( &self, From 0ed91b89ff6bfd5d2b36045f9bf7a6db1c7ef89c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 02:09:11 +0900 Subject: [PATCH 052/233] Add test for Blog::outbox_collection() --- plume-models/src/blogs.rs | 63 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 33c3586c..8e8776b0 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -644,8 +644,14 @@ impl NewBlog { pub(crate) mod tests { use super::*; use crate::{ - blog_authors::*, instance::tests as instance_tests, medias::NewMedia, tests::db, - users::tests as usersTests, Connection as Conn, + blog_authors::*, + instance::tests as instance_tests, + medias::NewMedia, + post_authors::{NewPostAuthor, PostAuthor}, + posts::{NewPost, Post}, + tests::db, + users::tests as usersTests, + Connection as Conn, ITEMS_PER_PAGE, }; use assert_json_diff::assert_json_eq; use diesel::Connection; @@ -727,6 +733,37 @@ pub(crate) mod tests { }, ) .unwrap(); + + for i in 1..(ITEMS_PER_PAGE * 4 + 3) { + let title = format!("Post {}", i); + let content = format!("Content for post {}.", i); + let post = Post::insert( + conn, + NewPost { + blog_id: blog1.id, + slug: title.clone(), + title: title.clone(), + content: SafeString::new(&content), + published: true, + license: "CC-0".into(), + creation_date: None, + ap_url: format!("{}/{}", blog1.ap_url, title), + subtitle: "".into(), + source: content, + cover_id: None, + }, + ) + .unwrap(); + PostAuthor::insert( + conn, + NewPostAuthor { + post_id: post.id, + author_id: users[0].id, + }, + ) + .unwrap(); + } + (users, vec![blog1, blog2, blog3]) } @@ -1090,4 +1127,26 @@ pub(crate) mod tests { Ok(()) }); } + + #[test] + fn outbox_collection() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (_users, blogs) = fill_database(conn); + let blog = &blogs[0]; + let act = blog.outbox_collection(conn)?; + + let expected = json!({ + "items": [], + "totalItems": 0, + "first": "https://plu.me/~/BlogName/outbox?page=1", + "last": "https://plu.me/~/BlogName/outbox?page=0", + "type": "OrderedCollection" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From e27fc47287c7fbd66ada231fde2598e11ba0db73 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 02:12:27 +0900 Subject: [PATCH 053/233] Extract Blog::outbox_collection_page() --- plume-models/src/blogs.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 8e8776b0..64672688 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -254,6 +254,14 @@ impl Blog { conn: &Connection, (min, max): (i32, i32), ) -> Result> { + self.outbox_collection_page(conn, (min, max)) + .map(|coll| ActivityStream::new(coll)) + } + pub fn outbox_collection_page( + &self, + conn: &Connection, + (min, max): (i32, i32), + ) -> Result { let mut coll = OrderedCollectionPage::default(); let acts = self.get_activity_page(conn, (min, max)); //This still doesn't do anything because the outbox @@ -269,7 +277,7 @@ impl Blog { min / ITEMS_PER_PAGE - 1 )))?; coll.collection_props.items = serde_json::to_value(acts)?; - Ok(ActivityStream::new(coll)) + Ok(coll) } fn get_activities(&self, _conn: &Connection) -> Vec { vec![] From f5e776c4d72bc753073c1ea8c36d15036aed5934 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 02:26:26 +0900 Subject: [PATCH 054/233] Fix first and last link in Blog::outbox_collection() --- plume-models/src/blogs.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 64672688..42cd39ed 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -1,5 +1,5 @@ use crate::{ - ap_url, db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString, + db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, }; use activitypub::{ @@ -239,14 +239,13 @@ impl Blog { coll.collection_props .set_total_items_u64(self.get_activities(conn).len() as u64)?; coll.collection_props - .set_first_link(Id::new(ap_url(&format!("{}?page=1", &self.outbox_url))))?; - coll.collection_props - .set_last_link(Id::new(ap_url(&format!( - "{}?page={}", - &self.outbox_url, - (self.get_activities(conn).len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64 - / ITEMS_PER_PAGE as u64 - ))))?; + .set_first_link(Id::new(&format!("{}?page=1", &self.outbox_url)))?; + coll.collection_props.set_last_link(Id::new(&format!( + "{}?page={}", + &self.outbox_url, + (self.get_activities(conn).len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64 + / ITEMS_PER_PAGE as u64 + )))?; Ok(coll) } pub fn outbox_page( From 67996cc938eb6b520f9d10f76c999fdd4163804d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Wed, 23 Feb 2022 02:29:01 +0900 Subject: [PATCH 055/233] Add test for Blog::outbox_collection_page() --- plume-models/src/blogs.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 42cd39ed..90f22ca2 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -1156,4 +1156,25 @@ pub(crate) mod tests { Ok(()) }); } + + #[test] + fn outbox_collection_page() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (_users, blogs) = fill_database(conn); + let blog = &blogs[0]; + let act = blog.outbox_collection_page(conn, (33, 36))?; + + let expected = json!({ + "next": "https://plu.me/~/BlogName/outbox?page=3", + "prev": "https://plu.me/~/BlogName/outbox?page=1", + "items": [], + "type": "OrderedCollectionPage" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 994a4dbb2d43d48dc1d9aee4484b4151c0a4c06d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 24 Feb 2022 01:58:05 +0900 Subject: [PATCH 056/233] Add source property to CustomGroup --- plume-common/src/activity_pub/mod.rs | 50 ++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 2a8e91a6..4ff4705f 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -8,7 +8,7 @@ use activitystreams::{ primitives::{AnyString, OneOrMany}, unparsed::UnparsedMutExt, }; -use activitystreams_ext::{Ext1, UnparsedExtension}; +use activitystreams_ext::{Ext1, Ext2, UnparsedExtension}; use array_tool::vec::Uniq; use reqwest::{header::HeaderValue, r#async::ClientBuilder, Url}; use rocket::{ @@ -344,8 +344,32 @@ where } } +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ActorSource { + pub source: Source, +} + +impl UnparsedExtension for ActorSource +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result { + Ok(ActorSource { + source: unparsed_mut.remove("source")?, + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert("source", self.source)?; + Ok(()) + } +} + pub type CustomPerson = Ext1, ApSignature07>; -pub type CustomGroup = Ext1, ApSignature07>; +pub type CustomGroup = Ext2, ApSignature07, ActorSource>; #[derive(Clone, Debug, Default, UnitString)] #[activitystreams(Hashtag)] @@ -364,7 +388,7 @@ pub struct Hashtag { pub name: Option, } -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Source { pub media_type: String, @@ -374,6 +398,26 @@ pub struct Source { impl Object for Source {} +impl UnparsedExtension for Source +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result { + Ok(Source { + content: unparsed_mut.remove("content")?, + media_type: unparsed_mut.remove("mediaType")?, + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert("content", self.content)?; + unparsed_mut.insert("mediaType", self.media_type)?; + Ok(()) + } +} + #[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] #[serde(rename_all = "camelCase")] pub struct Licensed { From 74d6dc508918f38697ae27ced358cfd57902fcfd Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 24 Feb 2022 02:40:36 +0900 Subject: [PATCH 057/233] Implement Blog::to_activity07(), outbox_collection07() and outbox_collection_page07() --- plume-models/src/blogs.rs | 299 +++++++++++++++++++++++++++++++++++--- 1 file changed, 276 insertions(+), 23 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 90f22ca2..241ab112 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -9,9 +9,13 @@ use activitypub::{ CustomObject, }; use activitystreams::{ - actor::AsApActor, + actor::{ApActor, ApActorExt, AsApActor, Group as Group07}, base::AnyBase, - object::{kind::ImageType, ApObject, ApObjectExt, Image as Image07, ObjectExt}, + collection::{ + OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, + }, + iri_string::types::IriString, + object::{kind::ImageType, ApObject, Image as Image07, ObjectExt}, prelude::*, }; use chrono::NaiveDateTime; @@ -24,15 +28,15 @@ use openssl::{ }; use plume_common::activity_pub::{ inbox::{AsActor, FromId, FromId07}, - sign, ActivityStream, ApSignature, CustomGroup as CustomGroup07, Id, IntoId, PublicKey, Source, - ToAsString, ToAsUri, + sign, ActivityStream, ActorSource, ApSignature, ApSignature07, CustomGroup as CustomGroup07, + Id, IntoId, PublicKey, PublicKey07, Source, ToAsString, ToAsUri, }; use url::Url; use webfinger::*; pub type CustomGroup = CustomObject; -#[derive(Queryable, Identifiable, Clone, AsChangeset)] +#[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)] #[changeset_options(treat_none_as_null = "true")] pub struct Blog { pub id: i32, @@ -229,9 +233,73 @@ impl Blog { Ok(CustomGroup::new(blog, ap_signature)) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut blog = ApActor::new(self.inbox_url.parse()?, Group07::new()); + blog.set_preferred_username(self.actor_id.clone()); + blog.set_name(self.title.clone()); + blog.set_outbox(self.outbox_url.parse()?); + blog.set_summary(self.summary_html.to_string()); + let source = ActorSource { + source: Source { + content: self.summary.clone(), + media_type: String::from("text/markdown"), + }, + }; + + let mut icon = Image07::new(); + let _ = self.icon_id.map(|id| { + Media::get(conn, id).and_then(|m| { + let _ = m + .url() + .and_then(|url| url.parse::().map_err(|_| Error::Url)) + .map(|url| icon.set_url(url)); + icon.set_attributed_to( + User::get(conn, m.owner_id)? + .into_id() + .parse::()?, + ); + Ok(()) + }) + }); + blog.set_icon(icon.into_any_base()?); + + let mut banner = Image07::new(); + let _ = self.banner_id.map(|id| { + Media::get(conn, id).and_then(|m| { + let _ = m + .url() + .and_then(|url| url.parse::().map_err(|_| Error::Url)) + .map(|url| banner.set_url(url)); + banner.set_attributed_to( + User::get(conn, m.owner_id)? + .into_id() + .parse::()?, + ); + Ok(()) + }) + }); + blog.set_image(banner.into_any_base()?); + + blog.set_id(self.ap_url.parse()?); + + let pub_key = PublicKey07 { + id: format!("{}#main-key", self.ap_url).parse()?, + owner: self.ap_url.parse()?, + public_key_pem: self.public_key.clone(), + }; + let ap_signature = ApSignature07 { + public_key: pub_key, + }; + + // assert_eq!("sumhtml", &self.summary_html.to_string()); + // assert_eq!("sum", blog.summary().unwrap().as_single_xsd_string().unwrap()); + // assert_eq!(json!({}), serde_json::to_value(&blog).unwrap()); + + Ok(CustomGroup07::new(blog, ap_signature, source)) + } + pub fn outbox(&self, conn: &Connection) -> Result> { - self.outbox_collection(conn) - .map(|coll| ActivityStream::new(coll)) + self.outbox_collection(conn).map(ActivityStream::new) } pub fn outbox_collection(&self, conn: &Connection) -> Result { let mut coll = OrderedCollection::default(); @@ -248,13 +316,34 @@ impl Blog { )))?; Ok(coll) } + pub fn outbox_collection07(&self, conn: &Connection) -> Result { + let acts = self.get_activities(conn); + let acts = acts + .iter() + .filter_map(|value| AnyBase::from_arbitrary_json(value).ok()) + .collect::>(); + let n_acts = acts.len(); + let mut coll = OrderedCollection07::new(); + coll.set_many_items(acts); + coll.set_total_items(n_acts as u64); + coll.set_first(format!("{}?page=1", &self.outbox_url).parse::()?); + coll.set_last( + format!( + "{}?page={}", + &self.outbox_url, + (n_acts as u64 + ITEMS_PER_PAGE as u64 - 1) as u64 / ITEMS_PER_PAGE as u64 + ) + .parse::()?, + ); + Ok(coll) + } pub fn outbox_page( &self, conn: &Connection, (min, max): (i32, i32), ) -> Result> { self.outbox_collection_page(conn, (min, max)) - .map(|coll| ActivityStream::new(coll)) + .map(ActivityStream::new) } pub fn outbox_collection_page( &self, @@ -278,6 +367,29 @@ impl Blog { coll.collection_props.items = serde_json::to_value(acts)?; Ok(coll) } + pub fn outbox_collection_page07( + &self, + conn: &Connection, + (min, max): (i32, i32), + ) -> Result { + let mut coll = OrderedCollectionPage07::new(); + let acts = self.get_activity_page(conn, (min, max)); + //This still doesn't do anything because the outbox + //doesn't do anything yet + coll.set_next( + format!("{}?page={}", &self.outbox_url, min / ITEMS_PER_PAGE + 1) + .parse::()?, + ); + coll.set_prev( + format!("{}?page={}", &self.outbox_url, min / ITEMS_PER_PAGE - 1) + .parse::()?, + ); + coll.set_many_items( + acts.iter() + .filter_map(|value| AnyBase::from_arbitrary_json(value).ok()), + ); + Ok(coll) + } fn get_activities(&self, _conn: &Connection) -> Vec { vec![] } @@ -506,7 +618,7 @@ impl FromId07 for Blog { new_blog.title = object .name() .and_then(|name| name.to_as_string()) - .unwrap_or_else(|| name); + .unwrap_or(name); new_blog.summary_html = SafeString::new( &object .summary() @@ -548,12 +660,7 @@ impl FromId07 for Blog { .map(|m| m.id); new_blog.banner_id = banner_id; - let source = object - .source() - .and_then(|s| s.as_xsd_string()) - .unwrap_or_default() - .to_string(); - new_blog.summary = source; + new_blog.summary = acct.ext_two.source.content; let any_base = AnyBase::from_extended(object)?; let id = any_base.id().ok_or(Error::MissingApProperty)?; @@ -667,7 +774,7 @@ pub(crate) mod tests { pub(crate) fn fill_database(conn: &Conn) -> (Vec, Vec) { instance_tests::fill_database(conn); let users = usersTests::fill_database(conn); - let blog1 = Blog::insert( + let mut blog1 = Blog::insert( conn, NewBlog::new_local( "BlogName".to_owned(), @@ -741,6 +848,40 @@ pub(crate) mod tests { ) .unwrap(); + blog1.icon_id = Some( + Media::insert( + conn, + NewMedia { + file_path: "aaa.png".into(), + alt_text: String::new(), + is_remote: false, + remote_url: None, + sensitive: false, + content_warning: None, + owner_id: users[0].id, + }, + ) + .unwrap() + .id, + ); + blog1.banner_id = Some( + Media::insert( + conn, + NewMedia { + file_path: "bbb.png".into(), + alt_text: String::new(), + is_remote: false, + remote_url: None, + sensitive: false, + content_warning: None, + owner_id: users[0].id, + }, + ) + .unwrap() + .id, + ); + let _: Blog = blog1.save_changes(&*conn).unwrap(); + for i in 1..(ITEMS_PER_PAGE * 4 + 3) { let title = format!("Post {}", i); let content = format!("Content for post {}.", i); @@ -1031,6 +1172,33 @@ pub(crate) mod tests { #[test] fn self_federation() { + let conn = &db(); + conn.test_transaction::<_, (), _>(|| { + let (_users, blogs) = fill_database(&conn); + + let ap_repr = blogs[0].to_activity(&conn).unwrap(); + blogs[0].delete(&conn).unwrap(); + let blog = Blog::from_activity(&conn, ap_repr).unwrap(); + + assert_eq!(blog.actor_id, blogs[0].actor_id); + assert_eq!(blog.title, blogs[0].title); + assert_eq!(blog.summary, blogs[0].summary); + assert_eq!(blog.outbox_url, blogs[0].outbox_url); + assert_eq!(blog.inbox_url, blogs[0].inbox_url); + assert_eq!(blog.instance_id, blogs[0].instance_id); + assert_eq!(blog.ap_url, blogs[0].ap_url); + assert_eq!(blog.public_key, blogs[0].public_key); + assert_eq!(blog.fqn, blogs[0].fqn); + assert_eq!(blog.summary_html, blogs[0].summary_html); + assert_eq!(blog.icon_url(&conn), blogs[0].icon_url(&conn)); + assert_eq!(blog.banner_url(&conn), blogs[0].banner_url(&conn)); + + Ok(()) + }) + } + + #[test] + fn self_federation07() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let (users, mut blogs) = fill_database(&conn); @@ -1067,10 +1235,9 @@ pub(crate) mod tests { .id, ); let _: Blog = blogs[0].save_changes(&**conn).unwrap(); - - let ap_repr = blogs[0].to_activity(&conn).unwrap(); + let ap_repr = blogs[0].to_activity07(&conn).unwrap(); blogs[0].delete(&conn).unwrap(); - let blog = Blog::from_activity(&conn, ap_repr).unwrap(); + let blog = Blog::from_activity07(&conn, ap_repr).unwrap(); assert_eq!(blog.actor_id, blogs[0].actor_id); assert_eq!(blog.title, blogs[0].title); @@ -1101,15 +1268,15 @@ pub(crate) mod tests { "followers": null, "following": null, "icon": { - "attributedTo": "", + "attributedTo": "https://plu.me/@/admin/", "type": "Image", - "url": "" + "url": "https://plu.me/aaa.png" }, "id": "https://plu.me/~/BlogName/", "image": { - "attributedTo": "", + "attributedTo": "https://plu.me/@/admin/", "type": "Image", - "url": "" + "url": "https://plu.me/bbb.png" }, "inbox": "https://plu.me/~/BlogName/inbox", "liked": null, @@ -1135,6 +1302,49 @@ pub(crate) mod tests { }); } + #[test] + fn to_activity07() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (_users, blogs) = fill_database(&conn); + let blog = &blogs[0]; + let act = blog.to_activity07(conn)?; + + let expected = json!({ + "icon": { + "attributedTo": "https://plu.me/@/admin/", + "type": "Image", + "url": "https://plu.me/aaa.png" + }, + "id": "https://plu.me/~/BlogName/", + "image": { + "attributedTo": "https://plu.me/@/admin/", + "type": "Image", + "url": "https://plu.me/bbb.png" + }, + "inbox": "https://plu.me/~/BlogName/inbox", + "name": "Blog name", + "outbox": "https://plu.me/~/BlogName/outbox", + "preferredUsername": "BlogName", + "publicKey": { + "id": "https://plu.me/~/BlogName/#main-key", + "owner": "https://plu.me/~/BlogName/", + "publicKeyPem": blog.public_key + }, + "source": { + "content": "This is a small blog", + "mediaType": "text/markdown" + }, + "summary": "", + "type": "Group" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn outbox_collection() { let conn = &db(); @@ -1157,6 +1367,28 @@ pub(crate) mod tests { }); } + #[test] + fn outbox_collection07() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (_users, blogs) = fill_database(conn); + let blog = &blogs[0]; + let act = blog.outbox_collection07(conn)?; + + let expected = json!({ + "items": [], + "totalItems": 0, + "first": "https://plu.me/~/BlogName/outbox?page=1", + "last": "https://plu.me/~/BlogName/outbox?page=0", + "type": "OrderedCollection" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn outbox_collection_page() { let conn = &db(); @@ -1177,4 +1409,25 @@ pub(crate) mod tests { Ok(()) }); } + + #[test] + fn outbox_collection_page07() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (_users, blogs) = fill_database(conn); + let blog = &blogs[0]; + let act = blog.outbox_collection_page07(conn, (33, 36))?; + + let expected = json!({ + "next": "https://plu.me/~/BlogName/outbox?page=3", + "prev": "https://plu.me/~/BlogName/outbox?page=1", + "items": [], + "type": "OrderedCollectionPage" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 5bd467c4c11cbfe1d87c3eb3f5b4de2251238ab4 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 24 Feb 2022 03:17:48 +0900 Subject: [PATCH 058/233] Remove unnecessary records --- plume-models/src/blogs.rs | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 241ab112..ecc7d4e3 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -291,10 +291,6 @@ impl Blog { public_key: pub_key, }; - // assert_eq!("sumhtml", &self.summary_html.to_string()); - // assert_eq!("sum", blog.summary().unwrap().as_single_xsd_string().unwrap()); - // assert_eq!(json!({}), serde_json::to_value(&blog).unwrap()); - Ok(CustomGroup07::new(blog, ap_signature, source)) } @@ -882,36 +878,6 @@ pub(crate) mod tests { ); let _: Blog = blog1.save_changes(&*conn).unwrap(); - for i in 1..(ITEMS_PER_PAGE * 4 + 3) { - let title = format!("Post {}", i); - let content = format!("Content for post {}.", i); - let post = Post::insert( - conn, - NewPost { - blog_id: blog1.id, - slug: title.clone(), - title: title.clone(), - content: SafeString::new(&content), - published: true, - license: "CC-0".into(), - creation_date: None, - ap_url: format!("{}/{}", blog1.ap_url, title), - subtitle: "".into(), - source: content, - cover_id: None, - }, - ) - .unwrap(); - PostAuthor::insert( - conn, - NewPostAuthor { - post_id: post.id, - author_id: users[0].id, - }, - ) - .unwrap(); - } - (users, vec![blog1, blog2, blog3]) } From 75b43a738fe06ce4a0789802ad25b9c3b06d08dc Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 25 Feb 2022 23:38:36 +0900 Subject: [PATCH 059/233] Follow clippy --- plume-models/src/blogs.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index ecc7d4e3..76853a50 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -754,14 +754,8 @@ impl NewBlog { pub(crate) mod tests { use super::*; use crate::{ - blog_authors::*, - instance::tests as instance_tests, - medias::NewMedia, - post_authors::{NewPostAuthor, PostAuthor}, - posts::{NewPost, Post}, - tests::db, - users::tests as usersTests, - Connection as Conn, ITEMS_PER_PAGE, + blog_authors::*, instance::tests as instance_tests, medias::NewMedia, tests::db, + users::tests as usersTests, Connection as Conn, }; use assert_json_diff::assert_json_eq; use diesel::Connection; From 95fb5a3c718285b44a635a650f4a6d733662177d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 26 Feb 2022 10:58:49 +0900 Subject: [PATCH 060/233] Implement Media::from_activity07() --- plume-models/src/medias.rs | 86 +++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 1af5f3b6..7d73b3b4 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -3,10 +3,11 @@ use crate::{ users::User, Connection, Error, Result, CONFIG, }; use activitypub::object::Image; +use activitystreams::{object::Image as Image07, prelude::*}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use guid_create::GUID; use plume_common::{ - activity_pub::{inbox::FromId, request, Id}, + activity_pub::{inbox::FromId, request, Id, ToAsString, ToAsUri}, utils::{escape, MediaProcessor}, }; use std::{ @@ -294,6 +295,89 @@ impl Media { }) } + // TODO: merge with save_remote? + pub fn from_activity07(conn: &DbConn, image: &Image07) -> Result { + let remote_url = image + .url() + .and_then(|url| url.to_as_uri()) + .ok_or(Error::MissingApProperty)?; + let path = determine_mirror_file_path(&remote_url); + let parent = path.parent().ok_or(Error::InvalidValue)?; + if !parent.is_dir() { + DirBuilder::new().recursive(true).create(parent)?; + } + + let mut dest = fs::File::create(path.clone())?; + // TODO: conditional GET + request::get( + remote_url.as_str(), + User::get_sender(), + CONFIG.proxy().cloned(), + )? + .copy_to(&mut dest)?; + + Media::find_by_file_path(conn, path.to_str().ok_or(Error::InvalidValue)?) + .and_then(|mut media| { + let mut updated = false; + + let alt_text = image + .content() + .and_then(|content| content.to_as_string()) + .ok_or(Error::NotFound)?; + let summary = image.summary().and_then(|summary| summary.to_as_string()); + let sensitive = summary.is_some(); + let content_warning = summary; + if media.alt_text != alt_text { + media.alt_text = alt_text; + updated = true; + } + if media.is_remote { + media.is_remote = false; + updated = true; + } + if media.sensitive != sensitive { + media.sensitive = sensitive; + updated = true; + } + if media.content_warning != content_warning { + media.content_warning = content_warning; + updated = true; + } + if updated { + diesel::update(&media).set(&media).execute(&**conn)?; + } + Ok(media) + }) + .or_else(|_| { + let summary = image.summary().and_then(|summary| summary.to_as_string()); + Media::insert( + conn, + NewMedia { + file_path: path.to_str().ok_or(Error::InvalidValue)?.to_string(), + alt_text: image + .content() + .and_then(|content| content.to_as_string()) + .ok_or(Error::NotFound)?, + is_remote: false, + remote_url: None, + sensitive: summary.is_some(), + content_warning: summary, + owner_id: User::from_id( + conn, + &image + .attributed_to() + .and_then(|attributed_to| attributed_to.to_as_uri()) + .ok_or(Error::MissingApProperty)?, + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)? + .id, + }, + ) + }) + } + pub fn get_media_processor<'a>(conn: &'a Connection, user: Vec<&User>) -> MediaProcessor<'a> { let uid = user.iter().map(|u| u.id).collect::>(); Box::new(move |id| { From b9dac1a21ae474121618ec2d4e4ca7199a57c9f1 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 6 Mar 2022 20:04:16 +0900 Subject: [PATCH 061/233] Define Hashtag07 --- plume-common/src/activity_pub/mod.rs | 128 ++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 4ff4705f..cbed4870 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,10 +1,11 @@ use activitypub::{Activity, Link, Object}; use activitystreams::{ actor::{ApActor, Group, Person}, - base::AnyBase, + base::{AnyBase, Base, Extends}, iri_string::types::IriString, - markers::Activity as Activity07, - object::{ApObject, Article}, + kind, + markers::{self, Activity as Activity07}, + object::{ApObject, Article, Object as Object07}, primitives::{AnyString, OneOrMany}, unparsed::UnparsedMutExt, }; @@ -388,6 +389,127 @@ pub struct Hashtag { pub name: Option, } +kind!(HashtagType07, Hashtag); + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +pub struct Hashtag07 { + #[serde(skip_serializing_if = "Option::is_none")] + pub href: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option, + + #[serde(flatten)] + inner: Object07, +} + +impl Hashtag07 { + pub fn new() -> Self { + Hashtag07 { + href: None, + name: None, + inner: Object07::new(), + } + } + + pub fn extending(mut inner: Object07) -> Result { + let href = inner.remove("href")?; + let name = inner.remove("name")?; + + Ok(Hashtag07 { href, name, inner }) + } + + pub fn retracting(self) -> Result, serde_json::Error> { + let Hashtag07 { + href, + name, + mut inner, + } = self; + + inner.insert("href", href)?; + inner.insert("name", name)?; + Ok(inner) + } +} + +pub trait AsHashtag: markers::Object { + fn hashtag_ref(&self) -> &Hashtag07; + + fn hashtag_mut(&mut self) -> &mut Hashtag07; +} + +pub trait HashtagExt: AsHashtag { + fn href(&self) -> Option<&IriString> { + self.hashtag_ref().href.as_ref() + } + + fn set_href(&mut self, href: T) -> &mut Self + where + T: Into, + { + self.hashtag_mut().href = Some(href.into()); + self + } + + fn take_href(&mut self) -> Option { + self.hashtag_mut().href.take() + } + + fn delete_href(&mut self) -> &mut Self { + self.hashtag_mut().href = None; + self + } + + fn name(&self) -> Option<&AnyString> { + self.hashtag_ref().name.as_ref() + } + + fn set_name(&mut self, name: T) -> &mut Self + where + T: Into, + { + self.hashtag_mut().name = Some(name.into()); + self + } + + fn take_name(&mut self) -> Option { + self.hashtag_mut().name.take() + } + + fn delete_name(&mut self) -> &mut Self { + self.hashtag_mut().name = None; + self + } +} + +impl AsHashtag for Hashtag07 { + fn hashtag_ref(&self) -> &Hashtag07 { + self + } + + fn hashtag_mut(&mut self) -> &mut Hashtag07 { + self + } +} + +impl Extends for Hashtag07 { + type Error = serde_json::Error; + + fn extends(base: Base) -> Result { + let inner = Object07::extends(base)?; + Self::extending(inner) + } + + fn retracts(self) -> Result, Self::Error> { + let inner = self.retracting()?; + inner.retracts() + } +} + +impl markers::Base for Hashtag07 {} +impl markers::Object for Hashtag07 {} +impl HashtagExt for T where T: AsHashtag {} + #[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Source { From 2b1ddc71ac69af11b56e40e9a02c90ed9bc7345d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 6 Mar 2022 20:04:42 +0900 Subject: [PATCH 062/233] Implement Tag::to_activity07() and Tag::build_activity07() --- plume-models/src/tags.rs | 73 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index 0460efc2..18072929 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -1,6 +1,7 @@ use crate::{ap_url, instance::Instance, schema::tags, Connection, Error, Result}; +use activitystreams::iri_string::types::IriString; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; -use plume_common::activity_pub::Hashtag; +use plume_common::activity_pub::{Hashtag, Hashtag07, HashtagExt}; #[derive(Clone, Identifiable, Queryable)] pub struct Tag { @@ -35,6 +36,20 @@ impl Tag { Ok(ht) } + pub fn to_activity07(&self) -> Result { + let mut ht = Hashtag07::new(); + ht.set_href( + ap_url(&format!( + "{}/tag/{}", + Instance::get_local()?.public_domain, + self.tag + )) + .parse::()?, + ); + ht.set_name(self.tag.clone()); + Ok(ht) + } + pub fn from_activity( conn: &Connection, tag: &Hashtag, @@ -62,6 +77,20 @@ impl Tag { Ok(ht) } + pub fn build_activity07(tag: String) -> Result { + let mut ht = Hashtag07::new(); + ht.set_href( + ap_url(&format!( + "{}/tag/{}", + Instance::get_local()?.public_domain, + tag + )) + .parse::()?, + ); + ht.set_name(tag); + Ok(ht) + } + pub fn delete(&self, conn: &Connection) -> Result<()> { diesel::delete(self) .execute(conn) @@ -137,4 +166,46 @@ mod tests { Ok(()) }); } + + #[test] + fn to_activity07() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + fill_database(conn); + let tag = Tag { + id: 0, + tag: "a_tag".into(), + is_hashtag: false, + post_id: 0, + }; + let act = tag.to_activity07()?; + let expected = json!({ + "href": "https://plu.me/tag/a_tag", + "name": "a_tag", + "type": "Hashtag" + }); + + assert_json_eq!(to_value(&act)?, expected); + + Ok(()) + }) + } + + #[test] + fn build_activity07() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + fill_database(conn); + let act = Tag::build_activity07("a_tag".into())?; + let expected = json!({ + "href": "https://plu.me/tag/a_tag", + "name": "a_tag", + "type": "Hashtag" + }); + + assert_json_eq!(to_value(&act)?, expected); + + Ok(()) + }); + } } From 2316d36e033771d85f262bfce1069f265a79e5b1 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 6 Mar 2022 21:19:56 +0900 Subject: [PATCH 063/233] Add test for Tag::from_activity07() --- plume-models/src/tags.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index 18072929..7631358b 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -66,6 +66,22 @@ impl Tag { ) } + pub fn from_activity07( + conn: &Connection, + tag: &Hashtag07, + post: i32, + is_hashtag: bool, + ) -> Result { + Tag::insert( + conn, + NewTag { + tag: tag.name().ok_or(Error::MissingApProperty)?.as_str().into(), + is_hashtag, + post_id: post, + }, + ) + } + pub fn build_activity(tag: String) -> Result { let mut ht = Hashtag::default(); ht.set_href_string(ap_url(&format!( From 1f5ce8e5049590681d891489e75d7888d85520a4 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 6 Mar 2022 22:00:37 +0900 Subject: [PATCH 064/233] Add test for Mention::build_activity07() and to_activity07() --- plume-models/src/mentions.rs | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 16672781..d6d027d9 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -3,6 +3,11 @@ use crate::{ users::User, Connection, Error, Result, }; use activitypub::link; +use activitystreams::{ + base::BaseExt, + iri_string::types::IriString, + link::{self as link07, LinkExt}, +}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::inbox::AsActor; @@ -64,6 +69,14 @@ impl Mention { Ok(mention) } + pub fn build_activity07(conn: &DbConn, ment: &str) -> Result { + let user = User::find_by_fqn(conn, ment)?; + let mut mention = link07::Mention::new(); + mention.set_href(user.ap_url.parse::()?); + mention.set_name(format!("@{}", ment)); + Ok(mention) + } + pub fn to_activity(&self, conn: &Connection) -> Result { let user = self.get_mentioned(conn)?; let mut mention = link::Mention::default(); @@ -74,6 +87,14 @@ impl Mention { Ok(mention) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let user = self.get_mentioned(conn)?; + let mut mention = link07::Mention::new(); + mention.set_href(user.ap_url.parse::()?); + mention.set_name(format!("@{}", user.fqn)); + Ok(mention) + } + pub fn from_activity( conn: &Connection, ment: &link::Mention, @@ -175,6 +196,27 @@ mod tests { }); } + #[test] + fn build_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (_posts, users, _blogs) = fill_database(&conn); + let user = &users[0]; + let name = &user.username; + let act = Mention::build_activity07(&conn, name)?; + + let expected = json!({ + "href": "https://plu.me/@/admin/", + "name": "@admin", + "type": "Mention", + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn to_activity() { let conn = db(); @@ -203,4 +245,33 @@ mod tests { Ok(()) }); } + + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (posts, users, _blogs) = fill_database(&conn); + let post = &posts[0]; + let user = &users[0]; + let mention = Mention::insert( + &conn, + NewMention { + mentioned_id: user.id, + post_id: Some(post.id), + comment_id: None, + }, + )?; + let act = mention.to_activity07(&conn)?; + + let expected = json!({ + "href": "https://plu.me/@/admin/", + "name": "@admin", + "type": "Mention", + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 70949fad024d8c4df2f045cf5dab72a40ae811ff Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 00:03:01 +0900 Subject: [PATCH 065/233] Rename: ActorSource -> SourceProperty --- plume-common/src/activity_pub/mod.rs | 8 ++++---- plume-models/src/blogs.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index cbed4870..40cbe05b 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -347,18 +347,18 @@ where #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct ActorSource { +pub struct SourceProperty { pub source: Source, } -impl UnparsedExtension for ActorSource +impl UnparsedExtension for SourceProperty where U: UnparsedMutExt, { type Error = serde_json::Error; fn try_from_unparsed(unparsed_mut: &mut U) -> Result { - Ok(ActorSource { + Ok(SourceProperty { source: unparsed_mut.remove("source")?, }) } @@ -370,7 +370,7 @@ where } pub type CustomPerson = Ext1, ApSignature07>; -pub type CustomGroup = Ext2, ApSignature07, ActorSource>; +pub type CustomGroup = Ext2, ApSignature07, SourceProperty>; #[derive(Clone, Debug, Default, UnitString)] #[activitystreams(Hashtag)] diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 76853a50..4428c6cc 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -28,8 +28,8 @@ use openssl::{ }; use plume_common::activity_pub::{ inbox::{AsActor, FromId, FromId07}, - sign, ActivityStream, ActorSource, ApSignature, ApSignature07, CustomGroup as CustomGroup07, - Id, IntoId, PublicKey, PublicKey07, Source, ToAsString, ToAsUri, + sign, ActivityStream, ApSignature, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, + PublicKey, PublicKey07, Source, SourceProperty, ToAsString, ToAsUri, }; use url::Url; use webfinger::*; @@ -239,7 +239,7 @@ impl Blog { blog.set_name(self.title.clone()); blog.set_outbox(self.outbox_url.parse()?); blog.set_summary(self.summary_html.to_string()); - let source = ActorSource { + let source = SourceProperty { source: Source { content: self.summary.clone(), media_type: String::from("text/markdown"), From 23f273e5e815a03ec69724e93100eb9a8bb1fa78 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 00:08:29 +0900 Subject: [PATCH 066/233] Readd assert-json-diff --- plume-common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index aadd464a..2ff06b99 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -37,6 +37,7 @@ git = "https://git.joinplu.me/Plume/pulldown-cmark" branch = "bidi-plume" [dev-dependencies] +assert-json-diff = "2.0.1" once_cell = "1.10.0" assert-json-diff = "2.0.1" From 216855d3a7edcb1cc69f5894ddac9fdc9aca995e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 00:15:19 +0900 Subject: [PATCH 067/233] Add SourceProperty to LicensedArticle --- plume-common/src/activity_pub/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 40cbe05b..622c5508 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -573,7 +573,7 @@ where } } -pub type LicensedArticle = Ext1, Licensed07>; +pub type LicensedArticle = Ext2, Licensed07, SourceProperty>; pub trait ToAsString { fn to_as_string(&self) -> Option; @@ -689,6 +689,12 @@ mod tests { Licensed07 { license: "CC-0".into(), }, + SourceProperty { + source: Source { + content: "content".into(), + media_type: "text/plain".into(), + }, + }, ); let expected = json!({ "type": "Article", From 7cf7700ef73f592be6deccd34f23f641b66a694b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 00:15:36 +0900 Subject: [PATCH 068/233] Implement Post::to_activity07() --- plume-models/src/posts.rs | 78 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 65c98735..51f27ab4 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -9,6 +9,13 @@ use activitypub::{ object::{Article, Image, Tombstone}, CustomObject, }; +use activitystreams::{ + base::AnyBase, + iri_string::types::IriString, + object::{ApObject, Article as Article07, Image as Image07}, + prelude::*, + time::OffsetDateTime, +}; use chrono::{NaiveDateTime, TimeZone, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; @@ -16,7 +23,8 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, Id, IntoId, Licensed, Source, PUBLIC_VISIBILITY, + Hashtag, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, + SourceProperty, PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, }; @@ -409,6 +417,74 @@ impl Post { Ok(LicensedArticle::new(article, license)) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let cc = self.get_receivers_urls(conn)?; + let to = vec![PUBLIC_VISIBILITY.to_string()]; + + let mut mentions_json = Mention::list_for_post(conn, self.id)? + .into_iter() + .map(|m| json!(m.to_activity07(conn).ok())) + .collect::>(); + let mut tags_json = Tag::for_post(conn, self.id)? + .into_iter() + .map(|t| json!(t.to_activity07().ok())) + .collect::>(); + mentions_json.append(&mut tags_json); + + let mut article = ApObject::new(Article07::new()); + article.set_name(self.title.clone()); + article.set_id(self.ap_url.parse::()?); + + let mut authors = self + .get_authors(conn)? + .into_iter() + .filter_map(|x| x.ap_url.parse::().ok()) + .collect::>(); + authors.push(self.get_blog(conn)?.ap_url.parse::()?); // add the blog URL here too + article.set_many_attributed_tos(authors); + article.set_content(self.content.get().clone()); + let source = SourceProperty { + content: self.source.clone(), + media_type: String::from("text/markdown"), + }; + article.set_published( + OffsetDateTime::from_unix_timestamp_nanos(self.creation_date.timestamp_nanos().into()) + .expect("OffsetDateTime"), + ); + article.set_summary(&*self.subtitle); + article.set_tag(AnyBase::from_arbitrary_json(json!(mentions_json))?); + + if let Some(media_id) = self.cover_id { + let media = Media::get(conn, media_id)?; + let mut cover = Image07::new(); + cover.set_url(media.url()?); + if media.sensitive { + cover.set_summary(media.content_warning.unwrap_or_default()); + } + cover.set_content(media.alt_text); + cover.set_many_attributed_tos(vec![User::get(conn, media.owner_id)? + .ap_url + .parse::()?]); + article.set_icon(cover.into_any_base()?); + } + + article.set_url(self.ap_url.parse::()?); + article.set_many_tos( + to.into_iter() + .filter_map(|to| to.parse::().ok()) + .collect::>(), + ); + article.set_many_ccs( + cc.into_iter() + .filter_map(|cc| cc.parse::().ok()) + .collect::>(), + ); + let license = Licensed07 { + license: self.license.clone(), + }; + Ok(LicensedArticle07::new(article, license, source)) + } + pub fn create_activity(&self, conn: &Connection) -> Result { let article = self.to_activity(conn)?; let mut act = Create::default(); From 53512a6167aeef8e9284e3569e68da47722d30bb Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 00:33:59 +0900 Subject: [PATCH 069/233] Fix SourceProperty property --- plume-models/src/posts.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 51f27ab4..b1e99fbd 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -444,8 +444,10 @@ impl Post { article.set_many_attributed_tos(authors); article.set_content(self.content.get().clone()); let source = SourceProperty { - content: self.source.clone(), - media_type: String::from("text/markdown"), + source: Source { + content: self.source.clone(), + media_type: String::from("text/markdown"), + }, }; article.set_published( OffsetDateTime::from_unix_timestamp_nanos(self.creation_date.timestamp_nanos().into()) From 05f4c186f432633e5f7b4745f3becfb43a20f13e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 03:24:53 +0900 Subject: [PATCH 070/233] Fix test for LicensedArticle serialization --- plume-common/src/activity_pub/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 622c5508..8a5f0fdc 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -698,7 +698,11 @@ mod tests { ); let expected = json!({ "type": "Article", - "license": "CC-0" + "license": "CC-0", + "source": { + "content": "content", + "mediaType": "text/plain" + } }); assert_json_eq!(to_value(licensed_article).unwrap(), expected); } From 21a0059755caa2f8a89a3d88287065b461778092 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 7 Mar 2022 03:48:55 +0900 Subject: [PATCH 071/233] Follow clippy --- plume-common/src/activity_pub/mod.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 8a5f0fdc..99317c58 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -405,7 +405,7 @@ pub struct Hashtag07 { impl Hashtag07 { pub fn new() -> Self { - Hashtag07 { + Self { href: None, name: None, inner: Object07::new(), @@ -416,11 +416,11 @@ impl Hashtag07 { let href = inner.remove("href")?; let name = inner.remove("name")?; - Ok(Hashtag07 { href, name, inner }) + Ok(Self { href, name, inner }) } pub fn retracting(self) -> Result, serde_json::Error> { - let Hashtag07 { + let Self { href, name, mut inner, @@ -482,12 +482,18 @@ pub trait HashtagExt: AsHashtag { } } +impl Default for Hashtag07 { + fn default() -> Self { + Self::new() + } +} + impl AsHashtag for Hashtag07 { - fn hashtag_ref(&self) -> &Hashtag07 { + fn hashtag_ref(&self) -> &Self { self } - fn hashtag_mut(&mut self) -> &mut Hashtag07 { + fn hashtag_mut(&mut self) -> &mut Self { self } } From d4018d61d4bf08b6a04f638238ef59f6210c0c79 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 06:38:28 +0900 Subject: [PATCH 072/233] Add test for Post::to_activity07() --- plume-models/src/posts.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index b1e99fbd..ced57612 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1174,6 +1174,44 @@ mod tests { }); } + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); + let act = post.to_activity07(&conn)?; + + let expected = json!({ + "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], + "cc": [], + "content": "Hello", + "id": "https://plu.me/~/BlogName/testing", + "license": "WTFPL", + "name": "Testing", + "published": format_datetime(&post.creation_date), + "source": { + "content": "", + "mediaType": "text/markdown" + }, + "summary": "", + "tag": [ + { + "href": "https://plu.me/@/user/", + "name": "@user", + "type": "Mention" + } + ], + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Article", + "url": "https://plu.me/~/BlogName/testing" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn create_activity() { let conn = db(); From c37ff54857994dabb01471ac79b043f8d1019411 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 06:38:39 +0900 Subject: [PATCH 073/233] Fix Post::to_activity07() --- plume-models/src/posts.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index ced57612..def48c3a 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -454,7 +454,11 @@ impl Post { .expect("OffsetDateTime"), ); article.set_summary(&*self.subtitle); - article.set_tag(AnyBase::from_arbitrary_json(json!(mentions_json))?); + article.set_many_tags( + mentions_json + .iter() + .filter_map(|mention_json| AnyBase::from_arbitrary_json(mention_json).ok()), + ); if let Some(media_id) = self.cover_id { let media = Media::get(conn, media_id)?; From 680d321a2e2d68087fd6cf997c3f6820cfb05bf7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 09:34:33 +0900 Subject: [PATCH 074/233] Implement Post::create_activity07() --- plume-models/src/posts.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index def48c3a..15963e39 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -10,7 +10,8 @@ use activitypub::{ CustomObject, }; use activitystreams::{ - base::AnyBase, + activity::Create as Create07, + base::{AnyBase, Base}, iri_string::types::IriString, object::{ApObject, Article as Article07, Image as Image07}, prelude::*, @@ -506,6 +507,20 @@ impl Post { Ok(act) } + pub fn create_activity07(&self, conn: &Connection) -> Result { + let article = self.to_activity07(conn)?; + let to = article.to().ok_or(Error::MissingApProperty)?.clone(); + let cc = article.cc().ok_or(Error::MissingApProperty)?.clone(); + let mut act = Create07::new( + self.get_authors(conn)?[0].ap_url.parse::()?, + Base::retract(article)?.into_generic()?, + ); + act.set_id(format!("{}/activity", self.ap_url).parse::()?); + act.set_many_tos(to); + act.set_many_ccs(cc); + Ok(act) + } + pub fn update_activity(&self, conn: &Connection) -> Result { let article = self.to_activity(conn)?; let mut act = Update::default(); From 871618f45d61358a49ffe25ebc6895eb462a41aa Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 09:34:42 +0900 Subject: [PATCH 075/233] Add test for Post::create_activity07() --- plume-models/src/posts.rs | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 15963e39..37de0777 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1276,6 +1276,51 @@ mod tests { }); } + #[test] + fn create_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); + let act = post.create_activity07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "cc": [], + "id": "https://plu.me/~/BlogName/testing/activity", + "object": { + "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], + "cc": [], + "content": "Hello", + "id": "https://plu.me/~/BlogName/testing", + "license": "WTFPL", + "name": "Testing", + "published": format_datetime(&post.creation_date), + "source": { + "content": "", + "mediaType": "text/markdown" + }, + "summary": "", + "tag": [ + { + "href": "https://plu.me/@/user/", + "name": "@user", + "type": "Mention" + } + ], + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Article", + "url": "https://plu.me/~/BlogName/testing" + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Create" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn update_activity() { let conn = db(); From 16e012ba00926c5d9708d84176f609511462a604 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 09:42:00 +0900 Subject: [PATCH 076/233] Implement Post::update_activity07() --- plume-models/src/posts.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 37de0777..981462dd 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -10,7 +10,7 @@ use activitypub::{ CustomObject, }; use activitystreams::{ - activity::Create as Create07, + activity::{Create as Create07, Update as Update07}, base::{AnyBase, Base}, iri_string::types::IriString, object::{ApObject, Article as Article07, Image as Image07}, @@ -539,6 +539,22 @@ impl Post { Ok(act) } + pub fn update_activity07(&self, conn: &Connection) -> Result { + let article = self.to_activity07(conn)?; + let to = article.to().ok_or(Error::MissingApProperty)?.clone(); + let cc = article.cc().ok_or(Error::MissingApProperty)?.clone(); + let mut act = Update07::new( + self.get_authors(conn)?[0].ap_url.parse::()?, + Base::retract(article)?.into_generic()?, + ); + act.set_id( + format!("{}/update-{}", self.ap_url, Utc::now().timestamp()).parse::()?, + ); + act.set_many_tos(to); + act.set_many_ccs(cc); + Ok(act) + } + pub fn update_mentions(&self, conn: &Connection, mentions: Vec) -> Result<()> { let mentions = mentions .into_iter() From 991dfccf3b9d3ad5cdf0b209a1989dfce63905fb Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 09:42:06 +0900 Subject: [PATCH 077/233] Add test for Post::update_activity07() --- plume-models/src/posts.rs | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 981462dd..9a8a7a43 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1402,4 +1402,70 @@ mod tests { Ok(()) }); } + + #[test] + fn update_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); + let act = post.update_activity07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "cc": [], + "id": "https://plu.me/~/BlogName/testing/update-", + "object": { + "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], + "cc": [], + "content": "Hello", + "id": "https://plu.me/~/BlogName/testing", + "license": "WTFPL", + "name": "Testing", + "published": format_datetime(&post.creation_date), + "source": { + "content": "", + "mediaType": "text/markdown" + }, + "summary": "", + "tag": [ + { + "href": "https://plu.me/@/user/", + "name": "@user", + "type": "Mention" + } + ], + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Article", + "url": "https://plu.me/~/BlogName/testing" + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Update" + }); + let actual = to_value(act)?; + + let id = actual["id"].to_string(); + let (id_pre, id_post) = id.rsplit_once("-").unwrap(); + assert_eq!(post.ap_url, "https://plu.me/~/BlogName/testing"); + assert_eq!( + id_pre, + to_value("\"https://plu.me/~/BlogName/testing/update") + .unwrap() + .as_str() + .unwrap() + ); + assert_eq!(id_post.len(), 11); + assert_eq!( + id_post.matches(char::is_numeric).collect::().len(), + 10 + ); + for (key, value) in actual.as_object().unwrap().into_iter() { + if key == "id" { + continue; + } + assert_eq!(value, expected.get(key).unwrap()); + } + + Ok(()) + }); + } } From 32cd91cfb97a662ebe25284456a59625b876f88d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 09:52:22 +0900 Subject: [PATCH 078/233] Implement Mention::from_activity07() --- plume-models/src/mentions.rs | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index d6d027d9..0d2fd415 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -138,6 +138,49 @@ impl Mention { } } + pub fn from_activity07( + conn: &Connection, + ment: &link07::Mention, + inside: i32, + in_post: bool, + notify: bool, + ) -> Result { + let ap_url = ment.href().ok_or(Error::NotFound)?.as_str(); + let mentioned = User::find_by_ap_url(conn, ap_url)?; + + if in_post { + Post::get(conn, inside).and_then(|post| { + let res = Mention::insert( + conn, + NewMention { + mentioned_id: mentioned.id, + post_id: Some(post.id), + comment_id: None, + }, + )?; + if notify { + res.notify(conn)?; + } + Ok(res) + }) + } else { + Comment::get(conn, inside).and_then(|comment| { + let res = Mention::insert( + conn, + NewMention { + mentioned_id: mentioned.id, + post_id: None, + comment_id: Some(comment.id), + }, + )?; + if notify { + res.notify(conn)?; + } + Ok(res) + }) + } + } + pub fn delete(&self, conn: &Connection) -> Result<()> { //find related notifications and delete them if let Ok(n) = Notification::find(conn, notification_kind::MENTION, self.id) { From e0390cb105ca047c0457eafbfe6d30e320e80037 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 09:54:52 +0900 Subject: [PATCH 079/233] Implement Post::update_mentions07() --- plume-models/src/posts.rs | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 9a8a7a43..e6fb195e 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -13,6 +13,7 @@ use activitystreams::{ activity::{Create as Create07, Update as Update07}, base::{AnyBase, Base}, iri_string::types::IriString, + link as link07, object::{ApObject, Article as Article07, Image as Image07}, prelude::*, time::OffsetDateTime, @@ -595,6 +596,48 @@ impl Post { Ok(()) } + pub fn update_mentions07( + &self, + conn: &Connection, + mentions: Vec, + ) -> Result<()> { + let mentions = mentions + .into_iter() + .map(|m| { + ( + m.href() + .and_then(|ap_url| User::find_by_ap_url(conn, ap_url.as_ref()).ok()) + .map(|u| u.id), + m, + ) + }) + .filter_map(|(id, m)| id.map(|id| (m, id))) + .collect::>(); + + let old_mentions = Mention::list_for_post(conn, self.id)?; + let old_user_mentioned = old_mentions + .iter() + .map(|m| m.mentioned_id) + .collect::>(); + for (m, id) in &mentions { + if !old_user_mentioned.contains(id) { + Mention::from_activity07(&*conn, m, self.id, true, true)?; + } + } + + let new_mentions = mentions + .into_iter() + .map(|(_m, id)| id) + .collect::>(); + for m in old_mentions + .iter() + .filter(|m| !new_mentions.contains(&m.mentioned_id)) + { + m.delete(conn)?; + } + Ok(()) + } + pub fn update_tags(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() From c1562f38683f564bca210772285dfbd1858d3019 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 10:08:00 +0900 Subject: [PATCH 080/233] Implement Post::update_tags07() --- plume-models/src/posts.rs | 41 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index e6fb195e..bd87714d 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -25,8 +25,8 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, - SourceProperty, PUBLIC_VISIBILITY, + Hashtag, Hashtag07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, + Source, SourceProperty, PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, }; @@ -674,6 +674,43 @@ impl Post { Ok(()) } + pub fn update_tags07(&self, conn: &Connection, tags: Vec) -> Result<()> { + let tags_name = tags + .iter() + .filter_map(|t| t.name.as_ref().map(|name| name.as_str().to_string())) + .collect::>(); + + let old_tags = Tag::for_post(&*conn, self.id)?; + let old_tags_name = old_tags + .iter() + .filter_map(|tag| { + if !tag.is_hashtag { + Some(tag.tag.clone()) + } else { + None + } + }) + .collect::>(); + + for t in tags { + if !t + .name + .as_ref() + .map(|n| old_tags_name.contains(n.as_str())) + .unwrap_or(true) + { + Tag::from_activity07(conn, &t, self.id, false)?; + } + } + + for ot in old_tags.iter().filter(|t| !t.is_hashtag) { + if !tags_name.contains(&ot.tag) { + ot.delete(conn)?; + } + } + Ok(()) + } + pub fn update_hashtags(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() From da7870eeba88cd84f69c9c839e9c995d072b9558 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 10:11:35 +0900 Subject: [PATCH 081/233] Implement Post::update_hashtags07() --- plume-models/src/posts.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index bd87714d..422f4b7d 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -747,6 +747,43 @@ impl Post { Ok(()) } + pub fn update_hashtags07(&self, conn: &Connection, tags: Vec) -> Result<()> { + let tags_name = tags + .iter() + .filter_map(|t| t.name.as_ref().map(|name| name.as_str().to_string())) + .collect::>(); + + let old_tags = Tag::for_post(&*conn, self.id)?; + let old_tags_name = old_tags + .iter() + .filter_map(|tag| { + if tag.is_hashtag { + Some(tag.tag.clone()) + } else { + None + } + }) + .collect::>(); + + for t in tags { + if !t + .name + .as_ref() + .map(|n| old_tags_name.contains(n.as_str())) + .unwrap_or(true) + { + Tag::from_activity07(conn, &t, self.id, true)?; + } + } + + for ot in old_tags.into_iter().filter(|t| t.is_hashtag) { + if !tags_name.contains(&ot.tag) { + ot.delete(conn)?; + } + } + Ok(()) + } + pub fn url(&self, conn: &Connection) -> Result { let blog = self.get_blog(conn)?; Ok(format!("/~/{}/{}", blog.fqn, self.slug)) From 98e07549769afe9e6e3518bd425425eb013d7453 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 10:24:18 +0900 Subject: [PATCH 082/233] Add test for Post::build_delete() --- plume-models/src/posts.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 422f4b7d..dbc194fc 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1585,4 +1585,30 @@ mod tests { Ok(()) }); } + + #[test] + fn build_delete() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); + let act = post.build_delete(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "id": "https://plu.me/~/BlogName/testing#delete", + "object": { + "id": "https://plu.me/~/BlogName/testing", + "type": "Tombstone" + }, + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "type": "Delete" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 3e9d9a81b786b1f71c4d308f95a1b0ec3a6446a0 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 10:32:12 +0900 Subject: [PATCH 083/233] Implement Mention::build_delete07() --- plume-models/src/posts.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index dbc194fc..a4bded7a 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -10,11 +10,11 @@ use activitypub::{ CustomObject, }; use activitystreams::{ - activity::{Create as Create07, Update as Update07}, + activity::{Create as Create07, Delete as Delete07, Update as Update07}, base::{AnyBase, Base}, iri_string::types::IriString, link as link07, - object::{ApObject, Article as Article07, Image as Image07}, + object::{ApObject, Article as Article07, Image as Image07, Tombstone as Tombstone07}, prelude::*, time::OffsetDateTime, }; @@ -811,6 +811,23 @@ impl Post { Ok(act) } + pub fn build_delete07(&self, conn: &Connection) -> Result { + let mut tombstone = Tombstone07::new(); + tombstone.set_id(self.ap_url.parse()?); + + let mut act = Delete07::new( + self.get_authors(conn)?[0] + .clone() + .into_id() + .parse::()?, + Base::retract(tombstone)?.into_generic()?, + ); + + act.set_id(format!("{}#delete", self.ap_url).parse()?); + act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + Ok(act) + } + fn publish_published(&self) { POST_CHAN.tell( Publish { From 6e2bff10f77a21f7f955010361c2dbad18cbbd08 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 21 Mar 2022 10:32:29 +0900 Subject: [PATCH 084/233] Add test for Post::build_delete07() --- plume-models/src/posts.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index a4bded7a..1e29f243 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1628,4 +1628,30 @@ mod tests { Ok(()) }); } + + #[test] + fn build_delete07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); + let act = post.build_delete07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "id": "https://plu.me/~/BlogName/testing#delete", + "object": { + "id": "https://plu.me/~/BlogName/testing", + "type": "Tombstone" + }, + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "type": "Delete" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 5e463e2cc9335b308b024da9e9f84e2945d00175 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 22 Mar 2022 00:20:53 +0900 Subject: [PATCH 085/233] Implement FromId07 for Post --- plume-models/src/posts.rs | 193 +++++++++++++++++++++++++++++++++++++- 1 file changed, 189 insertions(+), 4 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 1e29f243..8e374614 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -13,7 +13,7 @@ use activitystreams::{ activity::{Create as Create07, Delete as Delete07, Update as Update07}, base::{AnyBase, Base}, iri_string::types::IriString, - link as link07, + link::{self as link07, kind::MentionType}, object::{ApObject, Article as Article07, Image as Image07, Tombstone as Tombstone07}, prelude::*, time::OffsetDateTime, @@ -23,10 +23,11 @@ use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, sign::Signer, - Hashtag, Hashtag07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, - Source, SourceProperty, PUBLIC_VISIBILITY, + Hashtag, Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, + LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, + PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, }; @@ -1013,6 +1014,190 @@ impl FromId for Post { } } +impl FromId07 for Post { + type Error = Error; + type Object = LicensedArticle07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Self::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, article: LicensedArticle07) -> Result { + let license = article.ext_one.license; + let source = article.ext_two.source.content; + let article = article.inner; + + let (blog, authors) = article + .attributed_to() + .ok_or(Error::MissingApProperty) + .iter() + .fold((None, vec![]), |(blog, mut authors), link| { + let url = link.to_as_uri().expect("Exists"); + match User::from_id(conn, &url, None, CONFIG.proxy()) { + Ok(u) => { + authors.push(u); + (blog, authors) + } + Err(_) => ( + blog.or_else(|| Blog::from_id(conn, &url, None, CONFIG.proxy()).ok()), + authors, + ), + } + }); + + let cover = article.icon().and_then(|icon| { + icon.iter().next().and_then(|img| { + let image: Image07 = img.extend().ok()??; + Media::from_activity07(conn, &image).ok().map(|m| m.id) + }) + }); + + let title = article + .name() + .and_then(|name| name.to_as_string()) + .ok_or(Error::MissingApProperty)?; + let ap_url = article + .url() + .and_then(|url| { + url.to_as_uri().or_else(|| { + AnyBase::from_extended(article) + .ok()? + .id() + .map(|id| id.to_string()) + }) + }) + .ok_or(Error::MissingApProperty)?; + let post = Post::from_db07(conn, &ap_url) + .and_then(|mut post| { + let mut updated = false; + + let slug = Self::slug(&title); + let content = SafeString::new( + &article + .content() + .and_then(|content| content.to_as_string()) + .ok_or(Error::MissingApProperty)?, + ); + let subtitle = article + .summary() + .and_then(|summary| summary.to_as_string()) + .ok_or(Error::MissingApProperty)?; + + if post.slug != slug { + post.slug = slug.to_string(); + updated = true; + } + if post.title != title { + post.title = title.clone(); + updated = true; + } + if post.content != content { + post.content = content; + updated = true; + } + if post.license != license { + post.license = license.clone(); + updated = true; + } + if post.subtitle != subtitle { + post.subtitle = subtitle; + updated = true; + } + if post.source != source { + post.source = source; + updated = true; + } + if post.cover_id != cover { + post.cover_id = cover; + updated = true; + } + + if updated { + post.update(conn)?; + } + + Ok(post) + }) + .or_else(|_| { + Post::insert( + conn, + NewPost { + blog_id: blog.ok_or(Error::NotFound)?.id, + slug: Self::slug(&title).to_string(), + title, + content: SafeString::new( + &article + .content() + .and_then(|content| content.to_as_string()) + .ok_or(Error::MissingApProperty)?, + ), + published: true, + license, + // FIXME: This is wrong: with this logic, we may use the display URL as the AP ID. We need two different fields + ap_url, + creation_date: article.published().map(|published| { + let timestamp_secs = published.unix_timestamp(); + let timestamp_nanos = published.unix_timestamp_nanos() + - (timestamp_secs as i128) * 1000i128 * 1000i128 * 1000i128; + NaiveDateTime::from_timestamp(timestamp_secs, timestamp_nanos as u32) + }), + subtitle: article + .summary() + .and_then(|summary| summary.to_as_string()) + .ok_or(Error::MissingApProperty)?, + source: source, + cover_id: cover, + }, + ) + .and_then(|post| { + for author in authors { + PostAuthor::insert( + conn, + NewPostAuthor { + post_id: post.id, + author_id: author.id, + }, + )?; + } + + Ok(post) + }) + })?; + + // save mentions and tags + let mut hashtags = md_to_html(&post.source, None, false, None) + .2 + .into_iter() + .collect::>(); + if let Some(tags) = article.tag() { + for tag in tags.iter() { + tag.extend::() + .map(|mention| { + mention.map(|m| Mention::from_activity07(conn, &m, post.id, true, true)) + }) + .ok(); + + tag.extend::() + .and_then(|hashtag| { + Ok(hashtag.and_then(|t| { + let tag_name = t.name?.as_str(); + Tag::from_activity07(conn, &t, post.id, hashtags.remove(tag_name)).ok() + })) + }) + .ok(); + } + } + + Timeline::add_to_all_timelines(conn, &post, Kind::Original)?; + + Ok(post) + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to get local instance user") + } +} + impl AsObject for Post { type Error = Error; type Output = Post; From 9183d04e6674f8b6a67f3fb8892bee56b242e646 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 19:22:09 +0900 Subject: [PATCH 086/233] Fix Post::from_activity07() for borrow checker --- plume-models/src/posts.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 8e374614..f857d462 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -14,7 +14,9 @@ use activitystreams::{ base::{AnyBase, Base}, iri_string::types::IriString, link::{self as link07, kind::MentionType}, - object::{ApObject, Article as Article07, Image as Image07, Tombstone as Tombstone07}, + object::{ + kind::ImageType, ApObject, Article as Article07, Image as Image07, Tombstone as Tombstone07, + }, prelude::*, time::OffsetDateTime, }; @@ -1047,7 +1049,7 @@ impl FromId07 for Post { let cover = article.icon().and_then(|icon| { icon.iter().next().and_then(|img| { - let image: Image07 = img.extend().ok()??; + let image = img.to_owned().extend::().ok()??; Media::from_activity07(conn, &image).ok().map(|m| m.id) }) }); @@ -1056,16 +1058,14 @@ impl FromId07 for Post { .name() .and_then(|name| name.to_as_string()) .ok_or(Error::MissingApProperty)?; + let id = AnyBase::from_extended(article.clone()) // FIXME: Don't clone + .ok() + .ok_or(Error::MissingApProperty)? + .id() + .map(|id| id.to_string()); let ap_url = article .url() - .and_then(|url| { - url.to_as_uri().or_else(|| { - AnyBase::from_extended(article) - .ok()? - .id() - .map(|id| id.to_string()) - }) - }) + .and_then(|url| url.to_as_uri().or(id)) .ok_or(Error::MissingApProperty)?; let post = Post::from_db07(conn, &ap_url) .and_then(|mut post| { @@ -1104,7 +1104,7 @@ impl FromId07 for Post { updated = true; } if post.source != source { - post.source = source; + post.source = source.clone(); // FIXME: Don't clone updated = true; } if post.cover_id != cover { @@ -1171,17 +1171,19 @@ impl FromId07 for Post { .collect::>(); if let Some(tags) = article.tag() { for tag in tags.iter() { - tag.extend::() + tag.clone() + .extend::() // FIXME: Don't clone .map(|mention| { mention.map(|m| Mention::from_activity07(conn, &m, post.id, true, true)) }) .ok(); - tag.extend::() + tag.clone() + .extend::() // FIXME: Don't clone .and_then(|hashtag| { Ok(hashtag.and_then(|t| { - let tag_name = t.name?.as_str(); - Tag::from_activity07(conn, &t, post.id, hashtags.remove(tag_name)).ok() + let tag_name = t.name.clone()?.as_str().to_string(); + Tag::from_activity07(conn, &t, post.id, hashtags.remove(&tag_name)).ok() })) }) .ok(); From 01e8b0bce84c959e9b077f128f86716f3ed02e8b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 19:22:30 +0900 Subject: [PATCH 087/233] Implement AsObject for Post --- plume-models/src/posts.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index f857d462..dd08af41 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1210,6 +1210,16 @@ impl AsObject for Post { } } +impl AsObject07 for Post { + type Error = Error; + type Output = Self; + + fn activity07(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { + // TODO: check that _actor is actually one of the author? + Ok(self) + } +} + impl AsObject for Post { type Error = Error; type Output = (); @@ -1227,6 +1237,23 @@ impl AsObject for Post { } } +impl AsObject07 for Post { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result { + let can_delete = self + .get_authors(conn)? + .into_iter() + .any(|a| actor.id == a.id); + if can_delete { + self.delete(conn).map(|_| ()) + } else { + Err(Error::Unauthorized) + } + } +} + pub struct PostUpdate { pub ap_url: String, pub title: Option, From 489156f4a3baba9218ac061d82164a30e2647eca Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 19:25:32 +0900 Subject: [PATCH 088/233] Add test for Post's self federation --- plume-models/src/posts.rs | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index dd08af41..2590760f 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1476,6 +1476,56 @@ mod tests { }); } + // creates a post, get it's Create activity, delete the post, + // "send" the Create to the inbox, and check it works + #[test] + fn self_federation07() { + let conn = &db(); + conn.test_transaction::<_, (), _>(|| { + let (_, users, blogs) = fill_database(&conn); + let post = Post::insert( + &conn, + NewPost { + blog_id: blogs[0].id, + slug: "yo".into(), + title: "Yo".into(), + content: SafeString::new("Hello"), + published: true, + license: "WTFPL".to_string(), + creation_date: None, + ap_url: String::new(), // automatically updated when inserting + subtitle: "Testing".into(), + source: "Hello".into(), + cover_id: None, + }, + ) + .unwrap(); + PostAuthor::insert( + &conn, + NewPostAuthor { + post_id: post.id, + author_id: users[0].id, + }, + ) + .unwrap(); + let create = post.create_activity07(&conn).unwrap(); + post.delete(&conn).unwrap(); + + match inbox(&conn, serde_json::to_value(create).unwrap()).unwrap() { + InboxResult::Post(p) => { + assert!(p.is_author(&conn, users[0].id).unwrap()); + assert_eq!(p.source, "Hello".to_owned()); + assert_eq!(p.blog_id, blogs[0].id); + assert_eq!(p.content, SafeString::new("Hello")); + assert_eq!(p.subtitle, "Testing".to_owned()); + assert_eq!(p.title, "Yo".to_owned()); + } + _ => panic!("Unexpected result"), + }; + Ok(()) + }); + } + #[test] fn licensed_article_serde() { let mut article = Article::default(); From f854bc58381deeddd063790fb3abc87ae02487c9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 19:45:37 +0900 Subject: [PATCH 089/233] Add test for LicensedArticle deserialization --- plume-common/src/activity_pub/mod.rs | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 99317c58..df581358 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -712,4 +712,45 @@ mod tests { }); assert_json_eq!(to_value(licensed_article).unwrap(), expected); } + + #[test] + fn de_licensed_article() { + let value: LicensedArticle = from_str( + r#" + { + "type": "Article", + "id": "https://plu.me/~/Blog/my-article", + "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], + "content": "Hello.", + "name": "My Article", + "summary": "Bye.", + "source": { + "content": "Hello.", + "mediaType": "text/markdown" + }, + "published": "2014-12-12T12:12:12Z", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "license": "CC-0" + } + "#, + ) + .unwrap(); + let expected = json!({ + "type": "Article", + "id": "https://plu.me/~/Blog/my-article", + "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], + "content": "Hello.", + "name": "My Article", + "summary": "Bye.", + "source": { + "content": "Hello.", + "mediaType": "text/markdown" + }, + "published": "2014-12-12T12:12:12Z", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "license": "CC-0" + }); + + assert_eq!(to_value(value).unwrap(), expected); + } } From 86b4f622eaefdbee0415d722bb922f82c265d428 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 20:51:36 +0900 Subject: [PATCH 090/233] Implement Comment::to_activity07() --- plume-models/src/comments.rs | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 1da82a36..cee965a3 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -16,6 +16,9 @@ use activitypub::{ link, object::{Note, Tombstone}, }; +use activitystreams::{ + iri_string::types::IriString, object::Note as Note07, prelude::*, time::OffsetDateTime, +}; use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ @@ -141,6 +144,44 @@ impl Comment { Ok(note) } + pub fn to_activity07(&self, conn: &DbConn) -> Result { + let author = User::get(conn, self.author_id)?; + let (html, mentions, _hashtags) = utils::md_to_html( + self.content.get().as_ref(), + Some(&Instance::get_local()?.public_domain), + true, + Some(Media::get_media_processor(conn, vec![&author])), + ); + + let mut note = Note07::new(); + let to = vec![PUBLIC_VISIBILITY.parse::()?]; + + note.set_id( + self.ap_url + .clone() + .unwrap_or_default() + .parse::()?, + ); + note.set_summary(self.spoiler_text.clone()); + note.set_content(html); + note.set_in_reply_to(self.in_response_to_id.map_or_else( + || Post::get(conn, self.post_id).map(|post| post.ap_url), + |id| Comment::get(conn, id).map(|comment| comment.ap_url.unwrap_or_default()), + )?); + note.set_published( + OffsetDateTime::from_unix_timestamp_nanos(self.creation_date.timestamp_nanos().into()) + .expect("OffsetDateTime"), + ); + note.set_attributed_to(author.into_id().parse::()?); + note.set_many_tos(to); + note.set_many_tags(mentions.into_iter().filter_map(|m| { + Mention::build_activity07(conn, &m) + .map(|mention| mention.into_any_base().expect("Can convert")) + .ok() + })); + Ok(note) + } + pub fn create_activity(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; From 1c1dbd481abb528f2206636d59462429774ef201 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 20:51:47 +0900 Subject: [PATCH 091/233] Add test for Comment::to_activity07() --- plume-models/src/comments.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index cee965a3..fb7ef85f 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -596,6 +596,38 @@ mod tests { }); } + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (comment, _posts, _users, _blogs) = prepare_activity(&conn); + let act = comment.to_activity07(&conn)?; + + let expected = json!({ + "attributedTo": "https://plu.me/@/admin/", + "content": r###"

My comment, mentioning to @user

+"###, + "id": format!("https://plu.me/~/BlogName/testing/comment/{}", comment.id), + "inReplyTo": "https://plu.me/~/BlogName/testing", + "published": format_datetime(&comment.creation_date), + "summary": "My CW", + "tag": [ + { + "href": "https://plu.me/@/user/", + "name": "@user", + "type": "Mention" + } + ], + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Note" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn build_delete() { let conn = db(); From 88eb61c3204dcf92f7061102158befc6631c97cf Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 21:33:19 +0900 Subject: [PATCH 092/233] Implement Comment::create_activity07() --- plume-models/src/comments.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index fb7ef85f..17093dda 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -17,7 +17,8 @@ use activitypub::{ object::{Note, Tombstone}, }; use activitystreams::{ - iri_string::types::IriString, object::Note as Note07, prelude::*, time::OffsetDateTime, + activity::Create as Create07, base::Base, iri_string::types::IriString, object::Note as Note07, + prelude::*, time::OffsetDateTime, }; use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; @@ -200,6 +201,29 @@ impl Comment { Ok(act) } + pub fn create_activity07(&self, conn: &DbConn) -> Result { + let author = User::get(conn, self.author_id)?; + + let note = self.to_activity07(conn)?; + let to = note.to().ok_or(Error::MissingApProperty)?.clone(); + let cc = note.cc().ok_or(Error::MissingApProperty)?.clone(); + + let mut act = Create07::new( + author.into_id().parse::()?, + Base::retract(note)?.into_generic()?, + ); + act.set_id( + format!( + "{}/activity", + self.ap_url.clone().ok_or(Error::MissingApProperty)?, + ) + .parse::()?, + ); + act.set_many_tos(to); + act.set_many_ccs(cc); + Ok(act) + } + pub fn notify(&self, conn: &Connection) -> Result<()> { for author in self.get_post(conn)?.get_authors(conn)? { if Mention::list_for_comment(conn, self.id)? From 08ac7227b5a33c852e20a1c8cfd73257ed58114c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 21:44:21 +0900 Subject: [PATCH 093/233] Implement Comment::builde_delete07() --- plume-models/src/comments.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 17093dda..574c626c 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -17,8 +17,12 @@ use activitypub::{ object::{Note, Tombstone}, }; use activitystreams::{ - activity::Create as Create07, base::Base, iri_string::types::IriString, object::Note as Note07, - prelude::*, time::OffsetDateTime, + activity::{Create as Create07, Delete as Delete07}, + base::Base, + iri_string::types::IriString, + object::{Note as Note07, Tombstone as Tombstone07}, + prelude::*, + time::OffsetDateTime, }; use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; @@ -262,6 +266,26 @@ impl Comment { Ok(act) } + + pub fn build_delete07(&self, conn: &Connection) -> Result { + let mut tombstone = Tombstone07::new(); + tombstone.set_id( + self.ap_url + .as_ref() + .ok_or(Error::MissingApProperty)? + .parse::()?, + ); + + let mut act = Delete07::new( + self.get_author(conn)?.into_id().parse::()?, + Base::retract(tombstone)?.into_generic()?, + ); + + act.set_id(format!("{}#delete", self.ap_url.clone().unwrap()).parse::()?); + act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + + Ok(act) + } } impl FromId for Comment { From cf870971d148f66b94765e2a54c0956396363e66 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 3 Apr 2022 21:44:32 +0900 Subject: [PATCH 094/233] Add test for Comment::build_delete07() --- plume-models/src/comments.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 574c626c..4683daaf 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -699,4 +699,28 @@ mod tests { Ok(()) }); } + + #[test] + fn build_delete07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (comment, _posts, _users, _blogs) = prepare_activity(&conn); + let act = comment.build_delete07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "id": format!("https://plu.me/~/BlogName/testing/comment/{}#delete", comment.id), + "object": { + "id": format!("https://plu.me/~/BlogName/testing/comment/{}", comment.id), + "type": "Tombstone" + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Delete" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 1f6361a9a2e133b5f1fc0525332b01ec585e01e7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 18 Apr 2022 00:21:17 +0900 Subject: [PATCH 095/233] Fix Cargo.toml --- plume-common/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index 2ff06b99..6068289f 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -39,6 +39,5 @@ branch = "bidi-plume" [dev-dependencies] assert-json-diff = "2.0.1" once_cell = "1.10.0" -assert-json-diff = "2.0.1" [features] From 957725fbf81aa9f5122252ea9fee0e256a7bf512 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 23 Apr 2022 22:46:49 +0900 Subject: [PATCH 096/233] impl FromId07 for Comment --- plume-models/src/comments.rs | 145 ++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 4683daaf..ed2d684e 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -18,19 +18,21 @@ use activitypub::{ }; use activitystreams::{ activity::{Create as Create07, Delete as Delete07}, - base::Base, + base::{AnyBase, Base}, iri_string::types::IriString, + link::{self as link07, kind::MentionType}, object::{Note as Note07, Tombstone as Tombstone07}, prelude::*, + primitives::OneOrMany, time::OffsetDateTime, }; use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, FromId}, + inbox::{AsActor, AsObject, FromId, FromId07}, sign::Signer, - Id, IntoId, PUBLIC_VISIBILITY, + Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils, }; @@ -423,6 +425,143 @@ impl FromId for Comment { } } +impl FromId07 for Comment { + type Error = Error; + type Object = Note07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Self::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, note: Note07) -> Result { + let comm = { + let previous_url = note + .in_reply_to() + .ok_or(Error::MissingApProperty)? + .iter() + .next() + .ok_or(Error::MissingApProperty)? + .as_xsd_string() + .ok_or(Error::MissingApProperty)?; + let previous_comment = Comment::find_by_ap_url(conn, previous_url); + + let is_public = |v: &Option<&OneOrMany>| match v { + Some(one_or_many) => one_or_many.iter().any(|any_base| { + let xsd_string = any_base.as_xsd_string(); + xsd_string.is_some() && xsd_string.unwrap() == PUBLIC_VISIBILITY + }), + None => false, + }; + + let public_visibility = is_public(¬e.to()) + || is_public(¬e.bto()) + || is_public(¬e.cc()) + || is_public(¬e.bcc()); + + let summary = note.summary().and_then(|summary| summary.to_as_string()); + let sensitive = summary.is_some(); + let comm = Comment::insert( + conn, + NewComment { + content: SafeString::new( + ¬e + .content() + .ok_or(Error::MissingApProperty)? + .to_as_string() + .ok_or(Error::InvalidValue)?, + ), + spoiler_text: summary.unwrap_or_default(), + ap_url: Some( + note.id_unchecked() + .ok_or(Error::MissingApProperty)? + .to_string(), + ), + in_response_to_id: previous_comment.iter().map(|c| c.id).next(), + post_id: previous_comment.map(|c| c.post_id).or_else(|_| { + Ok(Post::find_by_ap_url(conn, previous_url)?.id) as Result + })?, + author_id: User::from_id( + conn, + ¬e + .attributed_to() + .ok_or(Error::MissingApProperty)? + .to_as_uri() + .ok_or(Error::MissingApProperty)?, + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)? + .id, + sensitive, + public_visibility, + }, + )?; + + // save mentions + if let Some(tags) = note.tag() { + let author_url = &Post::get(conn, comm.post_id)?.get_authors(conn)?[0].ap_url; + for tag in tags.iter() { + let m = tag.clone().extend::()?; // FIXME: Don't clone + if m.is_none() { + continue; + } + let m = m.unwrap(); + let not_author = m.href().ok_or(Error::MissingApProperty)? != author_url; + let _ = Mention::from_activity07(conn, &m, comm.id, false, not_author); + } + } + comm + }; + + if !comm.public_visibility { + let mut receiver_ids = HashSet::new(); + let mut receivers_id = |v: Option<&'_ OneOrMany>| { + if let Some(one_or_many) = v { + for any_base in one_or_many.iter() { + if let Some(id) = any_base.id() { + receiver_ids.insert(id.to_string()); + } + } + } + }; + + receivers_id(note.to()); + receivers_id(note.cc()); + receivers_id(note.bto()); + receivers_id(note.bcc()); + + let receivers_ap_url = receiver_ids + .into_iter() + .flat_map(|v| { + if let Ok(user) = User::from_id(conn, v.as_ref(), None, CONFIG.proxy()) { + vec![user] + } else { + vec![] // TODO try to fetch collection + } + }) + .filter(|u| u.get_instance(conn).map(|i| i.local).unwrap_or(false)) + .collect::>(); //remove duplicates (prevent db error) + + for user in &receivers_ap_url { + CommentSeers::insert( + conn, + NewCommentSeers { + comment_id: comm.id, + user_id: user.id, + }, + )?; + } + } + + comm.notify(conn)?; + Ok(comm) + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsObject for Comment { type Error = Error; type Output = Self; From 0c61dca9cadc81e759c6da984e94a2eb15d8e368 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 23 Apr 2022 22:49:13 +0900 Subject: [PATCH 097/233] Follow clippy --- plume-models/src/posts.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 2590760f..f112b098 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1145,7 +1145,7 @@ impl FromId07 for Post { .summary() .and_then(|summary| summary.to_as_string()) .ok_or(Error::MissingApProperty)?, - source: source, + source, cover_id: cover, }, ) @@ -1180,11 +1180,11 @@ impl FromId07 for Post { tag.clone() .extend::() // FIXME: Don't clone - .and_then(|hashtag| { - Ok(hashtag.and_then(|t| { + .map(|hashtag| { + hashtag.and_then(|t| { let tag_name = t.name.clone()?.as_str().to_string(); Tag::from_activity07(conn, &t, post.id, hashtags.remove(&tag_name)).ok() - })) + }) }) .ok(); } From 9969e844ca65807c2247bce11b5eeca0ca81dab7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 01:37:03 +0900 Subject: [PATCH 098/233] Add test for Comment self federation --- plume-models/src/comments.rs | 92 ++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index ed2d684e..a0f62f81 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -751,6 +751,98 @@ mod tests { }) } + // creates a post, get it's Create activity, delete the post, + // "send" the Create to the inbox, and check it works + #[test] + fn self_federation07() { + let conn = &db(); + conn.test_transaction::<_, (), _>(|| { + let (original_comm, posts, users, _blogs) = prepare_activity(&conn); + let act = original_comm.create_activity07(&conn).unwrap(); + + assert_json_eq!(to_value(&act).unwrap(), json!({ + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": format!("https://plu.me/~/BlogName/testing/comment/{}/activity", original_comm.id), + "object": { + "attributedTo": "https://plu.me/@/admin/", + "content": r###"

My comment, mentioning to @user

+"###, + "id": format!("https://plu.me/~/BlogName/testing/comment/{}", original_comm.id), + "inReplyTo": "https://plu.me/~/BlogName/testing", + "published": format_datetime(&original_comm.creation_date), + "summary": "My CW", + "tag": [ + { + "href": "https://plu.me/@/user/", + "name": "@user", + "type": "Mention" + } + ], + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Note" + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Create", + })); + + let reply = Comment::insert( + conn, + NewComment { + content: SafeString::new(""), + in_response_to_id: Some(original_comm.id), + post_id: posts[0].id, + author_id: users[1].id, + ap_url: None, + sensitive: false, + spoiler_text: "".into(), + public_visibility: true, + }, + ) + .unwrap(); + let reply_act = reply.create_activity07(&conn).unwrap(); + + assert_json_eq!(to_value(&reply_act).unwrap(), json!({ + "actor": "https://plu.me/@/user/", + "cc": ["https://plu.me/@/user/followers"], + "id": format!("https://plu.me/~/BlogName/testing/comment/{}/activity", reply.id), + "object": { + "attributedTo": "https://plu.me/@/user/", + "content": "", + "id": format!("https://plu.me/~/BlogName/testing/comment/{}", reply.id), + "inReplyTo": format!("https://plu.me/~/BlogName/testing/comment/{}", original_comm.id), + "published": format_datetime(&reply.creation_date), + "summary": "", + "tag": [], + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Note" + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Create" + })); + + inbox( + &conn, + serde_json::to_value(original_comm.build_delete07(&conn).unwrap()).unwrap(), + ) + .unwrap(); + + match inbox(&conn, to_value(act).unwrap()).unwrap() { + InboxResult::Commented(c) => { + // TODO: one is HTML, the other markdown: assert_eq!(c.content, original_comm.content); + assert_eq!(c.in_response_to_id, original_comm.in_response_to_id); + assert_eq!(c.post_id, original_comm.post_id); + assert_eq!(c.author_id, original_comm.author_id); + assert_eq!(c.ap_url, original_comm.ap_url); + assert_eq!(c.spoiler_text, original_comm.spoiler_text); + assert_eq!(c.public_visibility, original_comm.public_visibility); + } + _ => panic!("Unexpected result"), + }; + Ok(()) + }) + } + #[test] fn to_activity() { let conn = db(); From 713ffb950602eeffc47fe72bc3f07903ce5c46ab Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 01:37:30 +0900 Subject: [PATCH 099/233] Fix Comment::create_activity07() --- plume-models/src/comments.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index a0f62f81..37f800c3 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -211,8 +211,7 @@ impl Comment { let author = User::get(conn, self.author_id)?; let note = self.to_activity07(conn)?; - let to = note.to().ok_or(Error::MissingApProperty)?.clone(); - let cc = note.cc().ok_or(Error::MissingApProperty)?.clone(); + let note_clone = note.clone(); let mut act = Create07::new( author.into_id().parse::()?, @@ -225,8 +224,13 @@ impl Comment { ) .parse::()?, ); - act.set_many_tos(to); - act.set_many_ccs(cc); + act.set_many_tos( + note_clone + .to() + .iter() + .flat_map(|tos| tos.iter().map(|to| to.to_owned())), + ); + act.set_many_ccs(vec![self.get_author(conn)?.followers_endpoint]); Ok(act) } From ed55b662531dcca8dc86d05f68b709f134daa982 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 01:49:27 +0900 Subject: [PATCH 100/233] Implement AsObject07 for Comment --- plume-models/src/comments.rs | 41 +++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 37f800c3..2fe710ab 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -30,7 +30,7 @@ use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, sign::Signer, Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -605,6 +605,45 @@ impl AsObject for Comment { } } +impl AsObject07 for Comment { + type Error = Error; + type Output = Self; + + fn activity07(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { + // The actual creation takes place in the FromId impl + Ok(self) + } +} + +impl AsObject07 for Comment { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + if self.author_id != actor.id { + return Err(Error::Unauthorized); + } + + for m in Mention::list_for_comment(conn, self.id)? { + for n in Notification::find_for_mention(conn, &m)? { + n.delete(conn)?; + } + m.delete(conn)?; + } + + for n in Notification::find_for_comment(conn, &self)? { + n.delete(&**conn)?; + } + + diesel::update(comments::table) + .filter(comments::in_response_to_id.eq(self.id)) + .set(comments::in_response_to_id.eq(self.in_response_to_id)) + .execute(&**conn)?; + diesel::delete(&self).execute(&**conn)?; + Ok(()) + } +} + pub struct CommentTree { pub comment: Comment, pub responses: Vec, From c5656971c9d8436247ab7acc867fc88c18ec13ba Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 03:38:24 +0900 Subject: [PATCH 101/233] Add test for Follow::to_activity07() --- plume-models/src/follows.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index b1e6fdaf..3ebbef82 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -3,6 +3,12 @@ use crate::{ Connection, Error, Result, CONFIG, }; use activitypub::activity::{Accept, Follow as FollowAct, Undo}; +use activitystreams::{ + activity::{Accept as Accept07, Follow as FollowAct07}, + base::AnyBase, + iri_string::types::IriString, + prelude::*, +}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, @@ -310,6 +316,28 @@ mod tests { }); } + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (follow, _following, _follower, _users) = prepare_activity(&conn); + let act = follow.to_activity07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/other/", + "cc": ["https://www.w3.org/ns/activitystreams#Public"], + "id": format!("https://plu.me/follows/{}", follow.id), + "object": "https://plu.me/@/user/", + "to": ["https://plu.me/@/user/"], + "type": "Follow" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn build_accept() { let conn = db(); From 9343d3a120abe3b8075392a47250beb27b08f99a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 03:38:36 +0900 Subject: [PATCH 102/233] Implement Follow::to_activity07() --- plume-models/src/follows.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 3ebbef82..b31611d9 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -71,6 +71,19 @@ impl Follow { Ok(act) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let user = User::get(conn, self.follower_id)?; + let target = User::get(conn, self.following_id)?; + let target_id = target.ap_url.parse::()?; + + let mut act = FollowAct07::new(user.ap_url.parse::()?, target_id.clone()); + act.set_id(self.ap_url.parse::()?); + act.set_many_tos(vec![target_id]); + act.set_many_ccs(vec![PUBLIC_VISIBILITY.parse::()?]); + + Ok(act) + } + pub fn notify(&self, conn: &Connection) -> Result<()> { if User::get(conn, self.following_id)?.is_local() { Notification::insert( From 38a55857c6b223907ff253ecf8c0bae1ae448318 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 03:38:54 +0900 Subject: [PATCH 103/233] Add test for Follow::build_accept07() --- plume-models/src/follows.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index b31611d9..8061e5fb 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -380,6 +380,35 @@ mod tests { }); } + #[test] + fn build_accept07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (follow, following, follower, _users) = prepare_activity(&conn); + let act = follow.build_accept07(&follower, &following, follow.to_activity07(&conn)?)?; + + let expected = json!({ + "actor": "https://plu.me/@/user/", + "cc": ["https://www.w3.org/ns/activitystreams#Public"], + "id": format!("https://127.0.0.1:7878/follows/{}/accept", follow.id), + "object": { + "actor": "https://plu.me/@/other/", + "cc": ["https://www.w3.org/ns/activitystreams#Public"], + "id": format!("https://plu.me/follows/{}", follow.id), + "object": "https://plu.me/@/user/", + "to": ["https://plu.me/@/user/"], + "type": "Follow" + }, + "to": ["https://plu.me/@/other/"], + "type": "Accept" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn build_undo() { let conn = db(); From 9ca975113cbb3423bbadc44e34995ef14e1e33f1 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 03:39:08 +0900 Subject: [PATCH 104/233] Implement Follow::build_accept07() --- plume-models/src/follows.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 8061e5fb..1c48879b 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -155,6 +155,28 @@ impl Follow { Ok(accept) } + pub fn build_accept07 + IntoId, T>( + &self, + from: &B, + target: &A, + follow: FollowAct07, + ) -> Result { + let mut accept = Accept07::new( + target.clone().into_id().parse::()?, + AnyBase::from_extended(follow)?, + ); + let accept_id = ap_url(&format!( + "{}/follows/{}/accept", + CONFIG.base_url.as_str(), + self.id + )); + accept.set_id(accept_id.parse::()?); + accept.set_many_tos(vec![from.clone().into_id().parse::()?]); + accept.set_many_ccs(vec![PUBLIC_VISIBILITY.parse::()?]); + + Ok(accept) + } + pub fn build_undo(&self, conn: &Connection) -> Result { let mut undo = Undo::default(); undo.undo_props From 5f91345d6926418be3c4156359728b6f952ae88d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 03:45:11 +0900 Subject: [PATCH 105/233] Add test for Follow::build_undo07() --- plume-models/src/follows.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 1c48879b..75e19a38 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -4,7 +4,7 @@ use crate::{ }; use activitypub::activity::{Accept, Follow as FollowAct, Undo}; use activitystreams::{ - activity::{Accept as Accept07, Follow as FollowAct07}, + activity::{Accept as Accept07, Follow as FollowAct07, Undo as Undo07}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -452,4 +452,26 @@ mod tests { Ok(()) }); } + + #[test] + fn build_undo07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (follow, _following, _follower, _users) = prepare_activity(&conn); + let act = follow.build_undo07(&conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/other/", + "cc": ["https://www.w3.org/ns/activitystreams#Public"], + "id": format!("https://plu.me/follows/{}/undo", follow.id), + "object": format!("https://plu.me/follows/{}", follow.id), + "to": ["https://plu.me/@/user/"], + "type": "Undo" + }); + + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 174624f5c1d2d32e56d69dbbbe816ec98f3132bc Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 03:45:22 +0900 Subject: [PATCH 106/233] Implement Follow::build_undo07() --- plume-models/src/follows.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 75e19a38..d8a163ba 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -191,6 +191,22 @@ impl Follow { .set_cc_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; Ok(undo) } + + pub fn build_undo07(&self, conn: &Connection) -> Result { + let mut undo = Undo07::new( + User::get(conn, self.follower_id)? + .ap_url + .parse::()?, + self.ap_url.parse::()?, + ); + undo.set_id(format!("{}/undo", self.ap_url).parse::()?); + undo.set_many_tos(vec![User::get(conn, self.following_id)? + .ap_url + .parse::()?]); + undo.set_many_ccs(vec![PUBLIC_VISIBILITY.parse::()?]); + + Ok(undo) + } } impl AsObject for User { From f14c307786e70f22b2b25cfb015009e1cca7af6d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 05:47:11 +0900 Subject: [PATCH 107/233] Remove unused type parameter from broadcast07() --- plume-common/src/activity_pub/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index df581358..3462d564 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -196,7 +196,7 @@ where rt.run().unwrap(); } -pub fn broadcast07(sender: &S, act: A, to: Vec, proxy: Option) +pub fn broadcast07(sender: &S, act: A, to: Vec, proxy: Option) where S: sign::Signer, A: Activity07 + serde::Serialize, From 44799e94fda195875cd4f45dc9981cb0ebb37466 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 05:50:45 +0900 Subject: [PATCH 108/233] Implement Follow::accept_follow07() --- plume-models/src/follows.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index d8a163ba..df47b708 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -11,7 +11,7 @@ use activitystreams::{ }; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ - broadcast, + broadcast, broadcast07, inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, @@ -128,6 +128,39 @@ impl Follow { Ok(res) } + /// from -> The one sending the follow request + /// target -> The target of the request, responding with Accept + pub fn accept_follow07 + IntoId, T>( + conn: &Connection, + from: &B, + target: &A, + follow: FollowAct07, + from_id: i32, + target_id: i32, + ) -> Result { + let res = Follow::insert( + conn, + NewFollow { + follower_id: from_id, + following_id: target_id, + ap_url: follow + .id_unchecked() + .ok_or(Error::MissingApProperty)? + .to_string(), + }, + )?; + res.notify(conn)?; + + let accept = res.build_accept07(from, target, follow)?; + broadcast07( + &*target, + accept, + vec![from.clone()], + CONFIG.proxy().cloned(), + ); + Ok(res) + } + pub fn build_accept + IntoId, T>( &self, from: &B, From 86609b51faec52ac98f4d0b5b474e789c3e21d15 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 05:51:24 +0900 Subject: [PATCH 109/233] Implement AsObject07 for User --- plume-models/src/follows.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index df47b708..0aeaba90 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -12,7 +12,7 @@ use activitystreams::{ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, broadcast07, - inbox::{AsActor, AsObject, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -258,6 +258,18 @@ impl AsObject for User { } } +impl AsObject07 for User { + type Error = Error; + type Output = Follow; + + fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { + // Mastodon (at least) requires the full Follow object when accepting it, + // so we rebuilt it here + let follow = FollowAct07::new(id.parse::()?, actor.ap_url.parse::()?); + Follow::accept_follow07(conn, &actor, &self, follow, actor.id, self.id) + } +} + impl FromId for Follow { type Error = Error; type Object = FollowAct; From fb5027becd8885aa4ce5729225a059015e814af8 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:09:00 +0900 Subject: [PATCH 110/233] Implement FromId07 for Follow --- plume-models/src/follows.rs | 44 +++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 0aeaba90..ce853d1c 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -4,7 +4,7 @@ use crate::{ }; use activitypub::activity::{Accept, Follow as FollowAct, Undo}; use activitystreams::{ - activity::{Accept as Accept07, Follow as FollowAct07, Undo as Undo07}, + activity::{Accept as Accept07, ActorAndObjectRef, Follow as FollowAct07, Undo as Undo07}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -12,7 +12,7 @@ use activitystreams::{ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, broadcast07, - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -302,6 +302,46 @@ impl FromId for Follow { } } +impl FromId07 for Follow { + type Error = Error; + type Object = FollowAct07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Follow::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, follow: FollowAct07) -> Result { + let actor = User::from_id07( + conn, + follow + .actor_field_ref() + .as_single_id() + .ok_or(Error::MissingApProperty)? + .as_str(), + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)?; + + let target = User::from_id07( + conn, + follow + .object_field_ref() + .as_single_id() + .ok_or(Error::MissingApProperty)? + .as_str(), + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)?; + Follow::accept_follow07(conn, &actor, &target, follow, actor.id, target.id) + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsObject for Follow { type Error = Error; type Output = (); From 73009818f28d159ebc76dff950fb443463f3f9cd Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:11:54 +0900 Subject: [PATCH 111/233] Implement AsObject07 for Follow --- plume-models/src/follows.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index ce853d1c..8f597d83 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -363,6 +363,27 @@ impl AsObject for Follow { } } +impl AsObject07 for Follow { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + let conn = conn; + if self.follower_id == actor.id { + diesel::delete(&self).execute(&**conn)?; + + // delete associated notification if any + if let Ok(notif) = Notification::find(conn, notification_kind::FOLLOW, self.id) { + diesel::delete(¬if).execute(&**conn)?; + } + + Ok(()) + } else { + Err(Error::Unauthorized) + } + } +} + impl IntoId for Follow { fn into_id(self) -> Id { Id::new(self.ap_url) From 10acbdd41ffb77a28d2e8a6a718d47bed1be05df Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:33:39 +0900 Subject: [PATCH 112/233] Add test for Reshare::to_activity07() --- plume-models/src/reshares.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 90ca0cc8..05c5cc56 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -3,6 +3,7 @@ use crate::{ timeline::*, users::User, Connection, Error, Result, CONFIG, }; use activitypub::activity::{Announce, Undo}; +use activitystreams::{activity::Announce as Announce07, iri_string::types::IriString, prelude::*}; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ @@ -232,6 +233,30 @@ mod test { }); } + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (posts, _users, _blogs) = fill_database(&conn); + let post = &posts[0]; + let user = &post.get_authors(&conn)?[0]; + let reshare = Reshare::insert(&*conn, NewReshare::new(post, user))?; + let act = reshare.to_activity07(&conn).unwrap(); + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": "https://plu.me/@/admin/reshare/https://plu.me/~/BlogName/testing", + "object": "https://plu.me/~/BlogName/testing", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Announce", + }); + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn build_undo() { let conn = db(); From d78a57ce47f9010154835691e54b7296bb585791 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:34:00 +0900 Subject: [PATCH 113/233] Implement Reshare::to_ativity07() --- plume-models/src/reshares.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 05c5cc56..f2e8ee80 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -76,6 +76,21 @@ impl Reshare { Ok(act) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut act = Announce07::new( + User::get(conn, self.user_id)?.ap_url.parse::()?, + Post::get(conn, self.post_id)?.ap_url.parse::()?, + ); + act.set_id(self.ap_url.parse::()?); + act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + act.set_many_ccs(vec![self + .get_user(conn)? + .followers_endpoint + .parse::()?]); + + Ok(act) + } + pub fn notify(&self, conn: &Connection) -> Result<()> { let post = self.get_post(conn)?; for author in post.get_authors(conn)? { From e2702a187b23c2cf47ab40086193a3a8a38b02bd Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:35:50 +0900 Subject: [PATCH 114/233] Implement AsObject07 for Post --- plume-models/src/reshares.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index f2e8ee80..d21da516 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -7,7 +7,7 @@ use activitystreams::{activity::Announce as Announce07, iri_string::types::IriSt use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -145,6 +145,27 @@ impl AsObject for Post { } } +impl AsObject07 for Post { + type Error = Error; + type Output = Reshare; + + fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { + let conn = conn; + let reshare = Reshare::insert( + conn, + NewReshare { + post_id: self.id, + user_id: actor.id, + ap_url: id.to_string(), + }, + )?; + reshare.notify(conn)?; + + Timeline::add_to_all_timelines(conn, &self, Kind::Reshare(&actor))?; + Ok(reshare) + } +} + impl FromId for Reshare { type Error = Error; type Object = Announce; From f2a2bf2b2345b745e468c0b8f4beaa0427aa13ce Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:41:21 +0900 Subject: [PATCH 115/233] Implement FromId07 for Reshare --- plume-models/src/reshares.rs | 57 ++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index d21da516..e22fb7e8 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -3,11 +3,15 @@ use crate::{ timeline::*, users::User, Connection, Error, Result, CONFIG, }; use activitypub::activity::{Announce, Undo}; -use activitystreams::{activity::Announce as Announce07, iri_string::types::IriString, prelude::*}; +use activitystreams::{ + activity::{ActorAndObjectRef, Announce as Announce07}, + iri_string::types::IriString, + prelude::*, +}; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -206,6 +210,55 @@ impl FromId for Reshare { } } +impl FromId07 for Reshare { + type Error = Error; + type Object = Announce07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Reshare::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, act: Announce07) -> Result { + let res = Reshare::insert( + conn, + NewReshare { + post_id: Post::from_id( + conn, + act.object_field_ref() + .as_single_id() + .ok_or(Error::MissingApProperty)? + .as_str(), + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)? + .id, + user_id: User::from_id( + conn, + act.actor_field_ref() + .as_single_id() + .ok_or(Error::MissingApProperty)? + .as_str(), + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)? + .id, + ap_url: act + .id_unchecked() + .ok_or(Error::MissingApProperty)? + .to_string(), + }, + )?; + res.notify(conn)?; + Ok(res) + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsObject for Reshare { type Error = Error; type Output = (); From 08873990486b890f7636c12d7d331399d979ef1f Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:42:48 +0900 Subject: [PATCH 116/233] Implement AsObject07 for Reshare --- plume-models/src/reshares.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index e22fb7e8..8198edae 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -4,7 +4,7 @@ use crate::{ }; use activitypub::activity::{Announce, Undo}; use activitystreams::{ - activity::{ActorAndObjectRef, Announce as Announce07}, + activity::{ActorAndObjectRef, Announce as Announce07, Undo as Undo07}, iri_string::types::IriString, prelude::*, }; @@ -279,6 +279,26 @@ impl AsObject for Reshare { } } +impl AsObject07 for Reshare { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + if actor.id == self.user_id { + diesel::delete(&self).execute(&**conn)?; + + // delete associated notification if any + if let Ok(notif) = Notification::find(conn, notification_kind::RESHARE, self.id) { + diesel::delete(¬if).execute(&**conn)?; + } + + Ok(()) + } else { + Err(Error::Unauthorized) + } + } +} + impl NewReshare { pub fn new(p: &Post, u: &User) -> Self { let ap_url = format!("{}reshare/{}", u.ap_url, p.ap_url); From c814ac5681db0cbe29f066f871fef1c7972a5054 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:48:16 +0900 Subject: [PATCH 117/233] Add test for Reshare::build_undo07() --- plume-models/src/reshares.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 8198edae..6f74de55 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -396,4 +396,35 @@ mod test { Ok(()) }); } + + #[test] + fn build_undo07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (posts, _users, _blogs) = fill_database(&conn); + let post = &posts[0]; + let user = &post.get_authors(&conn)?[0]; + let reshare = Reshare::insert(&*conn, NewReshare::new(post, user))?; + let act = reshare.build_undo07(&*conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": "https://plu.me/@/admin/reshare/https://plu.me/~/BlogName/testing#delete", + "object": { + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": "https://plu.me/@/admin/reshare/https://plu.me/~/BlogName/testing", + "object": "https://plu.me/~/BlogName/testing", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Announce" + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Undo", + }); + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From 46f4676efb4fca5c978fc2f073057ac07a7b2029 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:48:31 +0900 Subject: [PATCH 118/233] Implement Reshare::build_undo07() --- plume-models/src/reshares.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 6f74de55..88269020 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -5,6 +5,7 @@ use crate::{ use activitypub::activity::{Announce, Undo}; use activitystreams::{ activity::{ActorAndObjectRef, Announce as Announce07, Undo as Undo07}, + base::AnyBase, iri_string::types::IriString, prelude::*, }; @@ -126,6 +127,21 @@ impl Reshare { Ok(act) } + + pub fn build_undo07(&self, conn: &Connection) -> Result { + let mut act = Undo07::new( + User::get(conn, self.user_id)?.ap_url.parse::()?, + AnyBase::from_extended(self.to_activity07(conn)?)?, + ); + act.set_id(format!("{}#delete", self.ap_url).parse::()?); + act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + act.set_many_ccs(vec![self + .get_user(conn)? + .followers_endpoint + .parse::()?]); + + Ok(act) + } } impl AsObject for Post { From bd3e6a5a914bad237a7b239823e61d59e81c57f7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:54:07 +0900 Subject: [PATCH 119/233] Replace some Inbox::with with with07 --- plume-models/src/inbox.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 8d744407..04cfb3f9 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -1,5 +1,5 @@ use activitypub::activity::*; -use activitystreams::activity::Delete as Delete07; +use activitystreams::activity::{Announce as Announce07, Delete as Delete07, Undo as Undo07}; use crate::{ comments::Comment, @@ -49,7 +49,7 @@ impl_into_inbox_result! { pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result { Inbox::handle(conn, act) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) @@ -57,8 +57,8 @@ pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) .done() From 6b8d90d8b68f1ec4fb493e5c7d7a055386342c06 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:58:17 +0900 Subject: [PATCH 120/233] Add test for Like::to_activity07() --- plume-models/src/likes.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 9c119177..3702d7b4 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -3,6 +3,7 @@ use crate::{ users::User, Connection, Error, Result, CONFIG, }; use activitypub::activity; +use activitystreams::{activity::Like as Like07, iri_string::types::IriString, prelude::*}; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ @@ -206,6 +207,30 @@ mod tests { }); } + #[test] + fn to_activity07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (posts, _users, _blogs) = fill_database(&conn); + let post = &posts[0]; + let user = &post.get_authors(&conn)?[0]; + let like = Like::insert(&*conn, NewLike::new(post, user))?; + let act = like.to_activity07(&conn).unwrap(); + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": "https://plu.me/@/admin/like/https://plu.me/~/BlogName/testing", + "object": "https://plu.me/~/BlogName/testing", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Like", + }); + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } + #[test] fn build_undo() { let conn = db(); From 4ea29d29a038fa38685b925f6cf56d4cc9ef387c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 06:58:33 +0900 Subject: [PATCH 121/233] Implement Like::to_activity07() --- plume-models/src/likes.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 3702d7b4..9a405904 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -51,6 +51,20 @@ impl Like { Ok(act) } + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut act = Like07::new( + User::get(conn, self.user_id)?.ap_url.parse::()?, + Post::get(conn, self.post_id)?.ap_url.parse::()?, + ); + act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + act.set_many_ccs(vec![User::get(conn, self.user_id)? + .followers_endpoint + .parse::()?]); + act.set_id(self.ap_url.parse::()?); + + Ok(act) + } + pub fn notify(&self, conn: &Connection) -> Result<()> { let post = Post::get(conn, self.post_id)?; for author in post.get_authors(conn)? { From 3093f713ef1a306cc66d1b17f516ccc3e34fd55d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 07:03:06 +0900 Subject: [PATCH 122/233] Add test for Like::build_undo07() --- plume-models/src/likes.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 9a405904..cad9d1ef 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -3,7 +3,12 @@ use crate::{ users::User, Connection, Error, Result, CONFIG, }; use activitypub::activity; -use activitystreams::{activity::Like as Like07, iri_string::types::IriString, prelude::*}; +use activitystreams::{ + activity::{Like as Like07, Undo as Undo07}, + base::AnyBase, + iri_string::types::IriString, + prelude::*, +}; use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ @@ -275,4 +280,35 @@ mod tests { Ok(()) }); } + + #[test] + fn build_undo07() { + let conn = db(); + conn.test_transaction::<_, Error, _>(|| { + let (posts, _users, _blogs) = fill_database(&conn); + let post = &posts[0]; + let user = &post.get_authors(&conn)?[0]; + let like = Like::insert(&*conn, NewLike::new(post, user))?; + let act = like.build_undo07(&*conn)?; + + let expected = json!({ + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": "https://plu.me/@/admin/like/https://plu.me/~/BlogName/testing#delete", + "object": { + "actor": "https://plu.me/@/admin/", + "cc": ["https://plu.me/@/admin/followers"], + "id": "https://plu.me/@/admin/like/https://plu.me/~/BlogName/testing", + "object": "https://plu.me/~/BlogName/testing", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Like", + }, + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "type": "Undo", + }); + assert_json_eq!(to_value(act)?, expected); + + Ok(()) + }); + } } From fcc9e1d81b5f8902b343b2ccea249321377b9b21 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 07:03:13 +0900 Subject: [PATCH 123/233] Implement Like::build_undo07() --- plume-models/src/likes.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index cad9d1ef..4eaf4778 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -102,6 +102,20 @@ impl Like { Ok(act) } + + pub fn build_undo07(&self, conn: &Connection) -> Result { + let mut act = Undo07::new( + User::get(conn, self.user_id)?.ap_url.parse::()?, + AnyBase::from_extended(self.to_activity07(conn)?)?, + ); + act.set_id(format!("{}#delete", self.ap_url).parse::()?); + act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); + act.set_many_ccs(vec![User::get(conn, self.user_id)? + .followers_endpoint + .parse::()?]); + + Ok(act) + } } impl AsObject for Post { From b2528c21ffbd3174d61fef4b982803b0e292e771 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 07:04:30 +0900 Subject: [PATCH 124/233] Implement AsObject07 for Post --- plume-models/src/likes.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 4eaf4778..3738d4d1 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -138,6 +138,26 @@ impl AsObject for Post { } } +impl AsObject07 for Post { + type Error = Error; + type Output = Like; + + fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { + let res = Like::insert( + conn, + NewLike { + post_id: self.id, + user_id: actor.id, + ap_url: id.to_string(), + }, + )?; + res.notify(conn)?; + + Timeline::add_to_all_timelines(conn, &self, Kind::Like(&actor))?; + Ok(res) + } +} + impl FromId for Like { type Error = Error; type Object = activity::Like; From a1c3bfb646d20f6ae15dec12bfa6641a7f009778 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 07:10:56 +0900 Subject: [PATCH 125/233] Implement FromId07 for Like --- plume-models/src/likes.rs | 53 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 3738d4d1..2190fbc7 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -4,7 +4,7 @@ use crate::{ }; use activitypub::activity; use activitystreams::{ - activity::{Like as Like07, Undo as Undo07}, + activity::{ActorAndObjectRef, Like as Like07, Undo as Undo07}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -198,6 +198,55 @@ impl FromId for Like { } } +impl FromId07 for Like { + type Error = Error; + type Object = Like07; + + fn from_db07(conn: &DbConn, id: &str) -> Result { + Like::find_by_ap_url(conn, id) + } + + fn from_activity07(conn: &DbConn, act: Like07) -> Result { + let res = Like::insert( + conn, + NewLike { + post_id: Post::from_id( + conn, + act.object_field_ref() + .as_single_id() + .ok_or(Error::MissingApProperty)? + .as_str(), + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)? + .id, + user_id: User::from_id07( + conn, + act.actor_field_ref() + .as_single_id() + .ok_or(Error::MissingApProperty)? + .as_str(), + None, + CONFIG.proxy(), + ) + .map_err(|(_, e)| e)? + .id, + ap_url: act + .id_unchecked() + .ok_or(Error::MissingApProperty)? + .to_string(), + }, + )?; + res.notify(conn)?; + Ok(res) + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsObject for Like { type Error = Error; type Output = (); From 3e54d1098189ebb583f90660a77ff6430179043d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 07:11:46 +0900 Subject: [PATCH 126/233] Implement AsObject07 for Like --- plume-models/src/likes.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 2190fbc7..202354dc 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -266,6 +266,25 @@ impl AsObject for Like { } } +impl AsObject07 for Like { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + if actor.id == self.user_id { + diesel::delete(&self).execute(&**conn)?; + + // delete associated notification if any + if let Ok(notif) = Notification::find(conn, notification_kind::LIKE, self.id) { + diesel::delete(¬if).execute(&**conn)?; + } + Ok(()) + } else { + Err(Error::Unauthorized) + } + } +} + impl NewLike { pub fn new(p: &Post, u: &User) -> Self { let ap_url = format!("{}like/{}", u.ap_url, p.ap_url); From 79b5d9a690ab0abffc3a307389d5da8cbd192225 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 24 Apr 2022 07:25:31 +0900 Subject: [PATCH 127/233] Replace Inbox::with() with with07() --- plume-models/src/inbox.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 04cfb3f9..0a9b36a2 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -1,5 +1,8 @@ use activitypub::activity::*; -use activitystreams::activity::{Announce as Announce07, Delete as Delete07, Undo as Undo07}; +use activitystreams::activity::{ + Announce as Announce07, Create as Create07, Delete as Delete07, Follow as Follow07, + Like as Like07, Undo as Undo07, Update as Update07, +}; use crate::{ comments::Comment, @@ -52,14 +55,14 @@ pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result(CONFIG.proxy()) .with::(CONFIG.proxy()) .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with::(CONFIG.proxy()) .done() } From 036913a8286350bb8803f30345d84ddf8c2e1e4a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 04:45:56 +0900 Subject: [PATCH 128/233] Use id() for reply_tos --- plume-models/src/comments.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 2fe710ab..b6c47fde 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -445,14 +445,14 @@ impl FromId07 for Comment { .iter() .next() .ok_or(Error::MissingApProperty)? - .as_xsd_string() + .id() .ok_or(Error::MissingApProperty)?; - let previous_comment = Comment::find_by_ap_url(conn, previous_url); + let previous_comment = Comment::find_by_ap_url(conn, previous_url.as_str()); let is_public = |v: &Option<&OneOrMany>| match v { Some(one_or_many) => one_or_many.iter().any(|any_base| { - let xsd_string = any_base.as_xsd_string(); - xsd_string.is_some() && xsd_string.unwrap() == PUBLIC_VISIBILITY + let id = any_base.id(); + id.is_some() && id.unwrap() == PUBLIC_VISIBILITY }), None => false, }; @@ -482,7 +482,7 @@ impl FromId07 for Comment { ), in_response_to_id: previous_comment.iter().map(|c| c.id).next(), post_id: previous_comment.map(|c| c.post_id).or_else(|_| { - Ok(Post::find_by_ap_url(conn, previous_url)?.id) as Result + Ok(Post::find_by_ap_url(conn, previous_url.as_str())?.id) as Result })?, author_id: User::from_id( conn, From 62372201e094fb1222a4b30508e9f3ba44301040 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 06:04:58 +0900 Subject: [PATCH 129/233] Fix inbox::tests::create_post() --- plume-models/src/inbox.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 0a9b36a2..0458c3f7 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -98,8 +98,8 @@ pub(crate) mod tests { license: "WTFPL".to_owned(), creation_date: None, ap_url: format!("https://plu.me/~/{}/testing", blogs[0].actor_id), - subtitle: String::new(), - source: String::new(), + subtitle: "Bye".to_string(), + source: "Hello".to_string(), cover_id: None, }, ) @@ -272,7 +272,7 @@ pub(crate) mod tests { "actor": users[0].ap_url, "object": { "type": "Article", - "id": "https://plu.me/~/Blog/my-article", + "id": "https://plu.me/~/BlogName/testing", "attributedTo": [users[0].ap_url, blogs[0].ap_url], "content": "Hello.", "name": "My Article", @@ -290,11 +290,11 @@ pub(crate) mod tests { match super::inbox(&conn, act).unwrap() { super::InboxResult::Post(p) => { assert!(p.is_author(&conn, users[0].id).unwrap()); - assert_eq!(p.source, "Hello.".to_owned()); + assert_eq!(p.source, "Hello".to_owned()); assert_eq!(p.blog_id, blogs[0].id); - assert_eq!(p.content, SafeString::new("Hello.")); - assert_eq!(p.subtitle, "Bye.".to_owned()); - assert_eq!(p.title, "My Article".to_owned()); + assert_eq!(p.content, SafeString::new("Hello")); + assert_eq!(p.subtitle, "Bye".to_owned()); + assert_eq!(p.title, "Testing".to_owned()); } _ => panic!("Unexpected result"), }; From 4e42a34337d679d7048f244ec08b7a4165942b77 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 06:05:20 +0900 Subject: [PATCH 130/233] Replace some with() with with07() --- plume-models/src/inbox.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 0458c3f7..6deb9722 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -53,8 +53,8 @@ impl_into_inbox_result! { pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result { Inbox::handle(conn, act) .with07::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) From 05df3b89a1abdd2513d7b9f11da1fe9602e25f0a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 07:45:05 +0900 Subject: [PATCH 131/233] Fix Follow::activity07() --- plume-models/src/follows.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 8f597d83..5d6beb43 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -265,7 +265,9 @@ impl AsObject07 for User { fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { // Mastodon (at least) requires the full Follow object when accepting it, // so we rebuilt it here - let follow = FollowAct07::new(id.parse::()?, actor.ap_url.parse::()?); + let mut follow = + FollowAct07::new(id.parse::()?, actor.ap_url.parse::()?); + follow.set_id(id.parse::()?); Follow::accept_follow07(conn, &actor, &self, follow, actor.id, self.id) } } From 76f688c967f5bf1125c7fe028fae63a03234c324 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 07:45:42 +0900 Subject: [PATCH 132/233] Replace some Inbox::with with with07 --- plume-models/src/inbox.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 6deb9722..d1a318fe 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -58,7 +58,7 @@ pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) From e5a28501056772362e80566c885e4ca3dbd7e051 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 09:56:03 +0900 Subject: [PATCH 133/233] Implement FromId07 for PostUpdate --- plume-models/src/posts.rs | 60 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index f112b098..e1dee790 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -15,7 +15,8 @@ use activitystreams::{ iri_string::types::IriString, link::{self as link07, kind::MentionType}, object::{ - kind::ImageType, ApObject, Article as Article07, Image as Image07, Tombstone as Tombstone07, + kind::ImageType, ApObject, Article as Article07, AsApObject, Image as Image07, + Tombstone as Tombstone07, }, prelude::*, time::OffsetDateTime, @@ -1302,6 +1303,63 @@ impl FromId for PostUpdate { } } +impl FromId07 for PostUpdate { + type Error = Error; + type Object = LicensedArticle07; + + fn from_db07(_: &DbConn, _: &str) -> Result { + // Always fail because we always want to deserialize the AP object + Err(Error::NotFound) + } + + fn from_activity07(conn: &DbConn, updated: Self::Object) -> Result { + let mut post_update = PostUpdate { + ap_url: updated + .ap_object_ref() + .id_unchecked() + .ok_or(Error::MissingApProperty)? + .to_string(), + title: updated + .ap_object_ref() + .name() + .and_then(|name| name.to_as_string()), + subtitle: updated + .ap_object_ref() + .summary() + .and_then(|summary| summary.to_as_string()), + content: updated + .ap_object_ref() + .content() + .and_then(|content| content.to_as_string()), + cover: None, + source: None, + license: None, + tags: updated + .tag() + .and_then(|tags| serde_json::to_value(tags).ok()), + }; + post_update.cover = updated.ap_object_ref().icon().and_then(|img| { + img.iter() + .next() + .and_then(|img| { + img.clone() + .extend::() + .map(|img| img.and_then(|img| Media::from_activity07(conn, &img).ok())) + .ok() + }) + .and_then(|m| m.map(|m| m.id)) + }); + post_update.source = Some(updated.ext_two.source.content); + post_update.license = Some(updated.ext_one.license); + + Ok(post_update) + } + + fn get_sender07() -> &'static dyn Signer { + Instance::get_local_instance_user().expect("Failed to local instance user") + } +} + impl AsObject for PostUpdate { type Error = Error; type Output = (); From 8f976be998694004d321c20abdaac544abd91618 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 09:56:16 +0900 Subject: [PATCH 134/233] Implement AsObject07 for PostUpdate --- plume-models/src/posts.rs | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index e1dee790..375f3a7f 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1432,6 +1432,78 @@ impl AsObject for PostUpdate { } } +impl AsObject07 for PostUpdate { + type Error = Error; + type Output = (); + + fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + let mut post = + Post::from_id(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; + + if !post.is_author(conn, actor.id)? { + // TODO: maybe the author was added in the meantime + return Err(Error::Unauthorized); + } + + if let Some(title) = self.title { + post.slug = Post::slug(&title).to_string(); + post.title = title; + } + + if let Some(content) = self.content { + post.content = SafeString::new(&content); + } + + if let Some(subtitle) = self.subtitle { + post.subtitle = subtitle; + } + + post.cover_id = self.cover; + + if let Some(source) = self.source { + post.source = source; + } + + if let Some(license) = self.license { + post.license = license; + } + + let mut txt_hashtags = md_to_html(&post.source, None, false, None) + .2 + .into_iter() + .collect::>(); + if let Some(serde_json::Value::Array(mention_tags)) = self.tags { + let mut mentions = vec![]; + let mut tags = vec![]; + let mut hashtags = vec![]; + for tag in mention_tags { + serde_json::from_value::(tag.clone()) + .map(|m| mentions.push(m)) + .ok(); + + serde_json::from_value::(tag.clone()) + .map_err(Error::from) + .and_then(|t| { + let tag_name = t.name_string()?; + if txt_hashtags.remove(&tag_name) { + hashtags.push(t); + } else { + tags.push(t); + } + Ok(()) + }) + .ok(); + } + post.update_mentions(conn, mentions)?; + post.update_tags(conn, tags)?; + post.update_hashtags(conn, hashtags)?; + } + + post.update(conn)?; + Ok(()) + } +} + impl IntoId for Post { fn into_id(self) -> Id { Id::new(self.ap_url) From 38ebc9ea41cc8a6ac04b3d2e17a347d633e38533 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 12:59:48 +0900 Subject: [PATCH 135/233] Modify test data for Post --- plume-models/src/posts.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 375f3a7f..37dfaea7 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1715,10 +1715,10 @@ mod tests { "name": "Testing", "published": format_datetime(&post.creation_date), "source": { - "content": "", + "content": "Hello", "mediaType": "text/markdown" }, - "summary": "", + "summary": "Bye", "tag": [ { "href": "https://plu.me/@/user/", @@ -1753,10 +1753,10 @@ mod tests { "name": "Testing", "published": format_datetime(&post.creation_date), "source": { - "content": "", + "content": "Hello", "mediaType": "text/markdown" }, - "summary": "", + "summary": "Bye", "tag": [ { "href": "https://plu.me/@/user/", @@ -1795,10 +1795,10 @@ mod tests { "name": "Testing", "published": format_datetime(&post.creation_date), "source": { - "content": "", + "content": "Hello", "mediaType": "text/markdown" }, - "summary": "", + "summary": "Bye", "tag": [ { "href": "https://plu.me/@/user/", @@ -1840,10 +1840,10 @@ mod tests { "name": "Testing", "published": format_datetime(&post.creation_date), "source": { - "content": "", + "content": "Hello", "mediaType": "text/markdown" }, - "summary": "", + "summary": "Bye", "tag": [ { "href": "https://plu.me/@/user/", @@ -1885,10 +1885,10 @@ mod tests { "name": "Testing", "published": format_datetime(&post.creation_date), "source": { - "content": "", + "content": "Hello", "mediaType": "text/markdown" }, - "summary": "", + "summary": "Bye", "tag": [ { "href": "https://plu.me/@/user/", @@ -1924,7 +1924,7 @@ mod tests { if key == "id" { continue; } - assert_eq!(value, expected.get(key).unwrap()); + assert_json_eq!(value, expected.get(key).unwrap()); } Ok(()) @@ -1951,10 +1951,10 @@ mod tests { "name": "Testing", "published": format_datetime(&post.creation_date), "source": { - "content": "", + "content": "Hello", "mediaType": "text/markdown" }, - "summary": "", + "summary": "Bye", "tag": [ { "href": "https://plu.me/@/user/", @@ -1990,7 +1990,7 @@ mod tests { if key == "id" { continue; } - assert_eq!(value, expected.get(key).unwrap()); + assert_json_eq!(value, expected.get(key).unwrap()); } Ok(()) From de6e9c0e2e24bcdc435d5d4aff4466c0a04eeb28 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 13:00:04 +0900 Subject: [PATCH 136/233] Fix Post::from_activity07() --- plume-models/src/posts.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 37dfaea7..a2ad8e0d 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -1031,20 +1031,27 @@ impl FromId07 for Post { let article = article.inner; let (blog, authors) = article + .ap_object_ref() .attributed_to() - .ok_or(Error::MissingApProperty) + .ok_or(Error::MissingApProperty)? .iter() .fold((None, vec![]), |(blog, mut authors), link| { - let url = link.to_as_uri().expect("Exists"); - match User::from_id(conn, &url, None, CONFIG.proxy()) { - Ok(u) => { - authors.push(u); - (blog, authors) + if let Some(url) = link.id() { + match User::from_id07(conn, url.as_str(), None, CONFIG.proxy()) { + Ok(u) => { + authors.push(u); + (blog, authors) + } + Err(_) => ( + blog.or_else(|| { + Blog::from_id07(conn, url.as_str(), None, CONFIG.proxy()).ok() + }), + authors, + ), } - Err(_) => ( - blog.or_else(|| Blog::from_id(conn, &url, None, CONFIG.proxy()).ok()), - authors, - ), + } else { + // logically, url possible to be an object without id proprty like {"type":"Person", "name":"Sally"} but we ignore the case + (blog, authors) } }); From 41bc2d6949632a11bd9492fba7c7c537f6863242 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 18:53:51 +0900 Subject: [PATCH 137/233] Make LicensedArticle's license fieald optional --- plume-common/src/activity_pub/mod.rs | 2 +- plume-models/src/inbox.rs | 2 +- plume-models/src/posts.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 3462d564..9ba7bfe0 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -558,7 +558,7 @@ impl Object for Licensed {} #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Licensed07 { - pub license: String, + pub license: Option, } impl UnparsedExtension for Licensed07 diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index d1a318fe..89683615 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -63,7 +63,7 @@ pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result(CONFIG.proxy()) .with07::(CONFIG.proxy()) .with07::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with07::(CONFIG.proxy()) .done() } diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index a2ad8e0d..7a1930eb 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -492,7 +492,7 @@ impl Post { .collect::>(), ); let license = Licensed07 { - license: self.license.clone(), + license: Some(self.license.clone()), }; Ok(LicensedArticle07::new(article, license, source)) } @@ -1026,7 +1026,7 @@ impl FromId07 for Post { } fn from_activity07(conn: &DbConn, article: LicensedArticle07) -> Result { - let license = article.ext_one.license; + let license = article.ext_one.license.unwrap_or_default(); let source = article.ext_two.source.content; let article = article.inner; @@ -1357,7 +1357,7 @@ impl FromId07 for PostUpdate { .and_then(|m| m.map(|m| m.id)) }); post_update.source = Some(updated.ext_two.source.content); - post_update.license = Some(updated.ext_one.license); + post_update.license = updated.ext_one.license; Ok(post_update) } From 7ade0550c951b6141b9a0694d05119854909f372 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 18:54:11 +0900 Subject: [PATCH 138/233] Remove unused import --- plume-models/src/inbox.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 89683615..9368f5be 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -1,4 +1,3 @@ -use activitypub::activity::*; use activitystreams::activity::{ Announce as Announce07, Create as Create07, Delete as Delete07, Follow as Follow07, Like as Like07, Undo as Undo07, Update as Update07, From c521a81373349a4024a45e30b3688acdee6bc850 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 19:13:38 +0900 Subject: [PATCH 139/233] Make test follow LicensedArticle change --- plume-common/src/activity_pub/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 9ba7bfe0..af74dd31 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -693,7 +693,7 @@ mod tests { let licensed_article = LicensedArticle::new( object, Licensed07 { - license: "CC-0".into(), + license: Some("CC-0".into()), }, SourceProperty { source: Source { From 8cbf410faf845367236f1cba20b800951c80c770 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 19:15:16 +0900 Subject: [PATCH 140/233] Remove execute permission from plume-common/src/lib.rs --- plume-common/src/lib.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plume-common/src/lib.rs diff --git a/plume-common/src/lib.rs b/plume-common/src/lib.rs old mode 100755 new mode 100644 From 2165c286aedf3d820cfc2f125219e62f441b13b9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 1 May 2022 19:49:12 +0900 Subject: [PATCH 141/233] Remove with() --- plume-common/src/activity_pub/inbox.rs | 78 -------------------------- 1 file changed, 78 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 5bcf5ed9..2537b1a4 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -196,84 +196,6 @@ where Inbox::NotHandled(ctx, json, InboxError::NoMatch) } - /// Registers an handler on this Inbox. - pub fn with(self, proxy: Option<&reqwest::Proxy>) -> Inbox<'a, C, E, R> - where - A: AsActor<&'a C> + FromId, - V: activitypub::Activity, - M: AsObject + FromId, - M::Output: Into, - { - if let Inbox::NotHandled(ctx, mut act, e) = self { - if serde_json::from_value::(act.clone()).is_ok() { - let act_clone = act.clone(); - let act_id = match act_clone["id"].as_str() { - Some(x) => x, - None => return Inbox::NotHandled(ctx, act, InboxError::InvalidID), - }; - - // Get the actor ID - let actor_id = match get_id(act["actor"].clone()) { - Some(x) => x, - None => return Inbox::NotHandled(ctx, act, InboxError::InvalidActor(None)), - }; - - if Self::is_spoofed_activity(&actor_id, &act) { - return Inbox::NotHandled(ctx, act, InboxError::InvalidObject(None)); - } - - // Transform this actor to a model (see FromId for details about the from_id function) - let actor = match A::from_id( - ctx, - &actor_id, - serde_json::from_value(act["actor"].clone()).ok(), - proxy, - ) { - Ok(a) => a, - // If the actor was not found, go to the next handler - Err((json, e)) => { - if let Some(json) = json { - act["actor"] = json; - } - return Inbox::NotHandled(ctx, act, InboxError::InvalidActor(Some(e))); - } - }; - - // Same logic for "object" - let obj_id = match get_id(act["object"].clone()) { - Some(x) => x, - None => return Inbox::NotHandled(ctx, act, InboxError::InvalidObject(None)), - }; - let obj = match M::from_id( - ctx, - &obj_id, - serde_json::from_value(act["object"].clone()).ok(), - proxy, - ) { - Ok(o) => o, - Err((json, e)) => { - if let Some(json) = json { - act["object"] = json; - } - return Inbox::NotHandled(ctx, act, InboxError::InvalidObject(Some(e))); - } - }; - - // Handle the activity - match obj.activity(ctx, actor, act_id) { - Ok(res) => Inbox::Handled(res.into()), - Err(e) => Inbox::Failed(e), - } - } else { - // If the Activity type is not matching the expected one for - // this handler, try with the next one. - Inbox::NotHandled(ctx, act, e) - } - } else { - self - } - } - /// Registers an handler on this Inbox. pub fn with07(self, proxy: Option<&reqwest::Proxy>) -> Self where From 2804f44a0621f735aa5c43f09a61c00e20a790fa Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 12:58:01 +0900 Subject: [PATCH 142/233] Rmove FromId --- plume-common/src/activity_pub/inbox.rs | 162 ------------------ plume-models/src/blogs.rs | 138 +-------------- plume-models/src/comments.rs | 141 +-------------- plume-models/src/follows.rs | 34 +--- plume-models/src/likes.rs | 44 +---- plume-models/src/medias.rs | 10 +- plume-models/src/posts.rs | 197 +-------------------- plume-models/src/remote_fetch_actor.rs | 28 ++- plume-models/src/reshares.rs | 46 +---- plume-models/src/users.rs | 226 +++++++------------------ src/inbox.rs | 4 +- src/routes/instance.rs | 6 +- 12 files changed, 107 insertions(+), 929 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 2537b1a4..9dba803c 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -318,72 +318,6 @@ fn get_id(json: serde_json::Value) -> Option { } } -/// A trait for ActivityPub objects that can be retrieved or constructed from ID. -/// -/// The two functions to implement are `from_activity` to create (and save) a new object -/// of this type from its AP representation, and `from_db` to try to find it in the database -/// using its ID. -/// -/// When dealing with the "object" field of incoming activities, `Inbox` will try to see if it is -/// a full object, and if so, save it with `from_activity`. If it is only an ID, it will try to find -/// it in the database with `from_db`, and otherwise dereference (fetch) the full object and parse it -/// with `from_activity`. -pub trait FromId: Sized { - /// The type representing a failure - type Error: From> + Debug; - - /// The ActivityPub object type representing Self - type Object: activitypub::Object; - - /// Tries to get an instance of `Self` from an ActivityPub ID. - /// - /// # Parameters - /// - /// - `ctx`: a context to get this instance (= a database in which to search) - /// - `id`: the ActivityPub ID of the object to find - /// - `object`: optional object that will be used if the object was not found in the database - /// If absent, the ID will be dereferenced. - fn from_id( - ctx: &C, - id: &str, - object: Option, - proxy: Option<&reqwest::Proxy>, - ) -> Result, Self::Error)> { - match Self::from_db(ctx, id) { - Ok(x) => Ok(x), - _ => match object { - Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)), - None => Self::from_activity(ctx, Self::deref(id, proxy.cloned())?) - .map_err(|e| (None, e)), - }, - } - } - - /// Dereferences an ID - fn deref( - id: &str, - proxy: Option, - ) -> Result, Self::Error)> { - request::get(id, Self::get_sender(), proxy) - .map_err(|_| (None, InboxError::DerefError)) - .and_then(|mut r| { - let json: serde_json::Value = r - .json() - .map_err(|_| (None, InboxError::InvalidObject(None)))?; - serde_json::from_value(json.clone()) - .map_err(|_| (Some(json), InboxError::InvalidObject(None))) - }) - .map_err(|(json, e)| (json, e.into())) - } - - /// Builds a `Self` from its ActivityPub representation - fn from_activity(ctx: &C, activity: Self::Object) -> Result; - - /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) - fn from_db(ctx: &C, id: &str) -> Result; - - fn get_sender() -> &'static dyn Signer; -} /// A trait for ActivityPub objects that can be retrieved or constructed from ID. /// /// The two functions to implement are `from_activity` to create (and save) a new object @@ -808,22 +742,6 @@ mod tests { } struct MyActor; - impl FromId<()> for MyActor { - type Error = (); - type Object = Person; - - fn from_db(_: &(), _id: &str) -> Result { - Ok(MyActor) - } - - fn from_activity(_: &(), _obj: Person) -> Result { - Ok(MyActor) - } - - fn get_sender() -> &'static dyn Signer { - &*MY_SIGNER - } - } impl FromId07<()> for MyActor { type Error = (); type Object = Person07; @@ -852,22 +770,6 @@ mod tests { } struct MyObject; - impl FromId<()> for MyObject { - type Error = (); - type Object = Note; - - fn from_db(_: &(), _id: &str) -> Result { - Ok(MyObject) - } - - fn from_activity(_: &(), _obj: Note) -> Result { - Ok(MyObject) - } - - fn get_sender() -> &'static dyn Signer { - &*MY_SIGNER - } - } impl AsObject for MyObject { type Error = (); type Output = (); @@ -1017,15 +919,6 @@ mod tests { act } - #[test] - fn test_inbox_basic() { - let act = serde_json::to_value(build_create()).unwrap(); - let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .done(); - assert!(res.is_ok()); - } - #[test] fn test_inbox_basic07() { let act = serde_json::to_value(build_create07()).unwrap(); @@ -1035,18 +928,6 @@ mod tests { assert!(res.is_ok()); } - #[test] - fn test_inbox_multi_handlers() { - let act = serde_json::to_value(build_create()).unwrap(); - let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .with::(None) - .with::(None) - .with::(None) - .done(); - assert!(res.is_ok()); - } - #[test] fn test_inbox_multi_handlers07() { let act = serde_json::to_value(build_create()).unwrap(); @@ -1059,17 +940,6 @@ mod tests { assert!(res.is_ok()); } - #[test] - fn test_inbox_failure() { - let act = serde_json::to_value(build_create()).unwrap(); - // Create is not handled by this inbox - let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .with::(None) - .done(); - assert!(res.is_err()); - } - #[test] fn test_inbox_failure07() { let act = serde_json::to_value(build_create07()).unwrap(); @@ -1082,22 +952,6 @@ mod tests { } struct FailingActor; - impl FromId<()> for FailingActor { - type Error = (); - type Object = Person; - - fn from_db(_: &(), _id: &str) -> Result { - Err(()) - } - - fn from_activity(_: &(), _obj: Person) -> Result { - Err(()) - } - - fn get_sender() -> &'static dyn Signer { - &*MY_SIGNER - } - } impl AsActor<&()> for FailingActor { fn get_inbox_url(&self) -> String { String::from("https://test.ap/failing-actor/inbox") @@ -1155,22 +1009,6 @@ mod tests { } } - #[test] - fn test_inbox_actor_failure() { - let act = serde_json::to_value(build_create()).unwrap(); - - let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with::(None) - .done(); - assert!(res.is_err()); - - let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with::(None) - .with::(None) - .done(); - assert!(res.is_ok()); - } - #[test] fn test_inbox_actor_failure07() { let act = serde_json::to_value(build_create07()).unwrap(); diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 4428c6cc..2de2e6ed 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -27,11 +27,10 @@ use openssl::{ sign::{Signer, Verifier}, }; use plume_common::activity_pub::{ - inbox::{AsActor, FromId, FromId07}, + inbox::{AsActor, FromId07}, sign, ActivityStream, ApSignature, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, PublicKey, PublicKey07, Source, SourceProperty, ToAsString, ToAsUri, }; -use url::Url; use webfinger::*; pub type CustomGroup = CustomObject; @@ -161,7 +160,7 @@ impl Blog { .find(|l| l.mime_type == Some(String::from("application/activity+json"))) .ok_or(Error::Webfinger) .and_then(|l| { - Blog::from_id( + Blog::from_id07( conn, &l.href.ok_or(Error::MissingApProperty)?, None, @@ -471,110 +470,6 @@ impl IntoId for Blog { } } -impl FromId for Blog { - type Error = Error; - type Object = CustomGroup; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Self::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, acct: CustomGroup) -> Result { - let url = Url::parse(&acct.object.object_props.id_string()?)?; - let inst = url.host_str().ok_or(Error::Url)?; - let instance = Instance::find_by_domain(conn, inst).or_else(|_| { - Instance::insert( - conn, - NewInstance { - public_domain: inst.to_owned(), - name: inst.to_owned(), - local: false, - // We don't really care about all the following for remote instances - long_description: SafeString::new(""), - short_description: SafeString::new(""), - default_license: String::new(), - open_registrations: true, - short_description_html: String::new(), - long_description_html: String::new(), - }, - ) - })?; - let icon_id = acct - .object - .object_props - .icon_image() - .ok() - .and_then(|icon| { - let owner = icon.object_props.attributed_to_link::().ok()?; - Media::save_remote( - conn, - icon.object_props.url_string().ok()?, - &User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?, - ) - .ok() - }) - .map(|m| m.id); - - let banner_id = acct - .object - .object_props - .image_image() - .ok() - .and_then(|banner| { - let owner = banner.object_props.attributed_to_link::().ok()?; - Media::save_remote( - conn, - banner.object_props.url_string().ok()?, - &User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?, - ) - .ok() - }) - .map(|m| m.id); - - let name = acct.object.ap_actor_props.preferred_username_string()?; - if name.contains(&['<', '>', '&', '@', '\'', '"', ' ', '\t'][..]) { - return Err(Error::InvalidValue); - } - - Blog::insert( - conn, - NewBlog { - actor_id: name.clone(), - title: acct.object.object_props.name_string().unwrap_or(name), - outbox_url: acct.object.ap_actor_props.outbox_string()?, - inbox_url: acct.object.ap_actor_props.inbox_string()?, - summary: acct - .object - .ap_object_props - .source_object::() - .map(|s| s.content) - .unwrap_or_default(), - instance_id: instance.id, - ap_url: acct.object.object_props.id_string()?, - public_key: acct - .custom_props - .public_key_publickey()? - .public_key_pem_string()?, - private_key: None, - banner_id, - icon_id, - summary_html: SafeString::new( - &acct - .object - .object_props - .summary_string() - .unwrap_or_default(), - ), - theme: None, - }, - ) - } - - fn get_sender() -> &'static dyn sign::Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for Blog { type Error = Error; type Object = CustomGroup07; @@ -648,7 +543,7 @@ impl FromId07 for Blog { Media::save_remote( conn, banner.url()?.to_as_uri()?, - &User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?, + &User::from_id07(conn, &owner, None, CONFIG.proxy()).ok()?, ) .ok() }) @@ -1130,33 +1025,6 @@ pub(crate) mod tests { }) } - #[test] - fn self_federation() { - let conn = &db(); - conn.test_transaction::<_, (), _>(|| { - let (_users, blogs) = fill_database(&conn); - - let ap_repr = blogs[0].to_activity(&conn).unwrap(); - blogs[0].delete(&conn).unwrap(); - let blog = Blog::from_activity(&conn, ap_repr).unwrap(); - - assert_eq!(blog.actor_id, blogs[0].actor_id); - assert_eq!(blog.title, blogs[0].title); - assert_eq!(blog.summary, blogs[0].summary); - assert_eq!(blog.outbox_url, blogs[0].outbox_url); - assert_eq!(blog.inbox_url, blogs[0].inbox_url); - assert_eq!(blog.instance_id, blogs[0].instance_id); - assert_eq!(blog.ap_url, blogs[0].ap_url); - assert_eq!(blog.public_key, blogs[0].public_key); - assert_eq!(blog.fqn, blogs[0].fqn); - assert_eq!(blog.summary_html, blogs[0].summary_html); - assert_eq!(blog.icon_url(&conn), blogs[0].icon_url(&conn)); - assert_eq!(blog.banner_url(&conn), blogs[0].banner_url(&conn)); - - Ok(()) - }) - } - #[test] fn self_federation07() { let conn = &db(); diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index b6c47fde..31df688b 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -30,7 +30,7 @@ use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId07}, sign::Signer, Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -294,141 +294,6 @@ impl Comment { } } -impl FromId for Comment { - type Error = Error; - type Object = Note; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Self::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, note: Note) -> Result { - let comm = { - let previous_url = note - .object_props - .in_reply_to - .as_ref() - .ok_or(Error::MissingApProperty)? - .as_str() - .ok_or(Error::MissingApProperty)?; - let previous_comment = Comment::find_by_ap_url(conn, previous_url); - - let is_public = |v: &Option| match v - .as_ref() - .unwrap_or(&serde_json::Value::Null) - { - serde_json::Value::Array(v) => v - .iter() - .filter_map(serde_json::Value::as_str) - .any(|s| s == PUBLIC_VISIBILITY), - serde_json::Value::String(s) => s == PUBLIC_VISIBILITY, - _ => false, - }; - - let public_visibility = is_public(¬e.object_props.to) - || is_public(¬e.object_props.bto) - || is_public(¬e.object_props.cc) - || is_public(¬e.object_props.bcc); - - let comm = Comment::insert( - conn, - NewComment { - content: SafeString::new(¬e.object_props.content_string()?), - spoiler_text: note.object_props.summary_string().unwrap_or_default(), - ap_url: note.object_props.id_string().ok(), - in_response_to_id: previous_comment.iter().map(|c| c.id).next(), - post_id: previous_comment.map(|c| c.post_id).or_else(|_| { - Ok(Post::find_by_ap_url(conn, previous_url)?.id) as Result - })?, - author_id: User::from_id( - conn, - ¬e.object_props.attributed_to_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)? - .id, - sensitive: note.object_props.summary_string().is_ok(), - public_visibility, - }, - )?; - - // save mentions - if let Some(serde_json::Value::Array(tags)) = note.object_props.tag.clone() { - for tag in tags { - serde_json::from_value::(tag) - .map_err(Error::from) - .and_then(|m| { - let author = &Post::get(conn, comm.post_id)?.get_authors(conn)?[0]; - let not_author = m.link_props.href_string()? != author.ap_url.clone(); - Mention::from_activity(conn, &m, comm.id, false, not_author) - }) - .ok(); - } - } - comm - }; - - if !comm.public_visibility { - let receivers_ap_url = |v: Option| { - let filter = |e: serde_json::Value| { - if let serde_json::Value::String(s) = e { - Some(s) - } else { - None - } - }; - match v.unwrap_or(serde_json::Value::Null) { - serde_json::Value::Array(v) => v, - v => vec![v], - } - .into_iter() - .filter_map(filter) - }; - - let mut note = note; - - let to = receivers_ap_url(note.object_props.to.take()); - let cc = receivers_ap_url(note.object_props.cc.take()); - let bto = receivers_ap_url(note.object_props.bto.take()); - let bcc = receivers_ap_url(note.object_props.bcc.take()); - - let receivers_ap_url = to - .chain(cc) - .chain(bto) - .chain(bcc) - .collect::>() // remove duplicates (don't do a query more than once) - .into_iter() - .flat_map(|v| { - if let Ok(user) = User::from_id(conn, &v, None, CONFIG.proxy()) { - vec![user] - } else { - vec![] // TODO try to fetch collection - } - }) - .filter(|u| u.get_instance(conn).map(|i| i.local).unwrap_or(false)) - .collect::>(); //remove duplicates (prevent db error) - - for user in &receivers_ap_url { - CommentSeers::insert( - conn, - NewCommentSeers { - comment_id: comm.id, - user_id: user.id, - }, - )?; - } - } - - comm.notify(conn)?; - Ok(comm) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for Comment { type Error = Error; type Object = Note07; @@ -484,7 +349,7 @@ impl FromId07 for Comment { post_id: previous_comment.map(|c| c.post_id).or_else(|_| { Ok(Post::find_by_ap_url(conn, previous_url.as_str())?.id) as Result })?, - author_id: User::from_id( + author_id: User::from_id07( conn, ¬e .attributed_to() @@ -537,7 +402,7 @@ impl FromId07 for Comment { let receivers_ap_url = receiver_ids .into_iter() .flat_map(|v| { - if let Ok(user) = User::from_id(conn, v.as_ref(), None, CONFIG.proxy()) { + if let Ok(user) = User::from_id07(conn, v.as_ref(), None, CONFIG.proxy()) { vec![user] } else { vec![] // TODO try to fetch collection diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 5d6beb43..6a2f3a9a 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -12,7 +12,7 @@ use activitystreams::{ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, broadcast07, - inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId07}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -272,38 +272,6 @@ impl AsObject07 for User { } } -impl FromId for Follow { - type Error = Error; - type Object = FollowAct; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Follow::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, follow: FollowAct) -> Result { - let actor = User::from_id( - conn, - &follow.follow_props.actor_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)?; - - let target = User::from_id( - conn, - &follow.follow_props.object_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)?; - Follow::accept_follow(conn, &actor, &target, follow, actor.id, target.id) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for Follow { type Error = Error; type Object = FollowAct07; diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 202354dc..8a7b0e23 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId07}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -158,46 +158,6 @@ impl AsObject07 for Post { } } -impl FromId for Like { - type Error = Error; - type Object = activity::Like; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Like::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, act: activity::Like) -> Result { - let res = Like::insert( - conn, - NewLike { - post_id: Post::from_id( - conn, - &act.like_props.object_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)? - .id, - user_id: User::from_id( - conn, - &act.like_props.actor_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)? - .id, - ap_url: act.object_props.id_string()?, - }, - )?; - res.notify(conn)?; - Ok(res) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for Like { type Error = Error; type Object = Like07; @@ -210,7 +170,7 @@ impl FromId07 for Like { let res = Like::insert( conn, NewLike { - post_id: Post::from_id( + post_id: Post::from_id07( conn, act.object_field_ref() .as_single_id() diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 7d73b3b4..13048292 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -7,7 +7,7 @@ use activitystreams::{object::Image as Image07, prelude::*}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use guid_create::GUID; use plume_common::{ - activity_pub::{inbox::FromId, request, Id, ToAsString, ToAsUri}, + activity_pub::{inbox::FromId07, request, Id, ToAsString, ToAsUri}, utils::{escape, MediaProcessor}, }; use std::{ @@ -222,7 +222,7 @@ impl Media { // TODO: conditional GET request::get( remote_url.as_str(), - User::get_sender(), + User::get_sender07(), CONFIG.proxy().cloned(), )? .copy_to(&mut dest)?; @@ -275,7 +275,7 @@ impl Media { remote_url: None, sensitive: image.object_props.summary_string().is_ok(), content_warning: image.object_props.summary_string().ok(), - owner_id: User::from_id( + owner_id: User::from_id07( conn, image .object_props @@ -311,7 +311,7 @@ impl Media { // TODO: conditional GET request::get( remote_url.as_str(), - User::get_sender(), + User::get_sender07(), CONFIG.proxy().cloned(), )? .copy_to(&mut dest)?; @@ -362,7 +362,7 @@ impl Media { remote_url: None, sensitive: summary.is_some(), content_warning: summary, - owner_id: User::from_id( + owner_id: User::from_id07( conn, &image .attributed_to() diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 7a1930eb..ad5bbebe 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -26,7 +26,7 @@ use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId07}, sign::Signer, Hashtag, Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, @@ -863,160 +863,6 @@ impl Post { } } -impl FromId for Post { - type Error = Error; - type Object = LicensedArticle; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Self::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, article: LicensedArticle) -> Result { - let conn = conn; - let license = article.custom_props.license_string().unwrap_or_default(); - let article = article.object; - - let (blog, authors) = article - .object_props - .attributed_to_link_vec::()? - .into_iter() - .fold((None, vec![]), |(blog, mut authors), link| { - let url = link; - match User::from_id(conn, &url, None, CONFIG.proxy()) { - Ok(u) => { - authors.push(u); - (blog, authors) - } - Err(_) => ( - blog.or_else(|| Blog::from_id(conn, &url, None, CONFIG.proxy()).ok()), - authors, - ), - } - }); - - let cover = article - .object_props - .icon_object::() - .ok() - .and_then(|img| Media::from_activity(conn, &img).ok().map(|m| m.id)); - - let title = article.object_props.name_string()?; - let ap_url = article - .object_props - .url_string() - .or_else(|_| article.object_props.id_string())?; - let post = Post::from_db(conn, &ap_url) - .and_then(|mut post| { - let mut updated = false; - - let slug = Self::slug(&title); - let content = SafeString::new(&article.object_props.content_string()?); - let subtitle = article.object_props.summary_string()?; - let source = article.ap_object_props.source_object::()?.content; - if post.slug != slug { - post.slug = slug.to_string(); - updated = true; - } - if post.title != title { - post.title = title.clone(); - updated = true; - } - if post.content != content { - post.content = content; - updated = true; - } - if post.license != license { - post.license = license.clone(); - updated = true; - } - if post.subtitle != subtitle { - post.subtitle = subtitle; - updated = true; - } - if post.source != source { - post.source = source; - updated = true; - } - if post.cover_id != cover { - post.cover_id = cover; - updated = true; - } - - if updated { - post.update(conn)?; - } - - Ok(post) - }) - .or_else(|_| { - Post::insert( - conn, - NewPost { - blog_id: blog.ok_or(Error::NotFound)?.id, - slug: Self::slug(&title).to_string(), - title, - content: SafeString::new(&article.object_props.content_string()?), - published: true, - license, - // FIXME: This is wrong: with this logic, we may use the display URL as the AP ID. We need two different fields - ap_url, - creation_date: Some(article.object_props.published_utctime()?.naive_utc()), - subtitle: article.object_props.summary_string()?, - source: article.ap_object_props.source_object::()?.content, - cover_id: cover, - }, - ) - .and_then(|post| { - for author in authors { - PostAuthor::insert( - conn, - NewPostAuthor { - post_id: post.id, - author_id: author.id, - }, - )?; - } - - Ok(post) - }) - })?; - - // save mentions and tags - let mut hashtags = md_to_html(&post.source, None, false, None) - .2 - .into_iter() - .collect::>(); - if let Some(serde_json::Value::Array(tags)) = article.object_props.tag { - for tag in tags { - serde_json::from_value::(tag.clone()) - .map(|m| Mention::from_activity(conn, &m, post.id, true, true)) - .ok(); - - serde_json::from_value::(tag.clone()) - .map_err(Error::from) - .and_then(|t| { - let tag_name = t.name_string()?; - Ok(Tag::from_activity( - conn, - &t, - post.id, - hashtags.remove(&tag_name), - )) - }) - .ok(); - } - } - - Timeline::add_to_all_timelines(conn, &post, Kind::Original)?; - - Ok(post) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for Post { type Error = Error; type Object = LicensedArticle07; @@ -1273,43 +1119,6 @@ pub struct PostUpdate { pub tags: Option, } -impl FromId for PostUpdate { - type Error = Error; - type Object = LicensedArticle; - - fn from_db(_: &DbConn, _: &str) -> Result { - // Always fail because we always want to deserialize the AP object - Err(Error::NotFound) - } - - fn from_activity(conn: &DbConn, updated: LicensedArticle) -> Result { - Ok(PostUpdate { - ap_url: updated.object.object_props.id_string()?, - title: updated.object.object_props.name_string().ok(), - subtitle: updated.object.object_props.summary_string().ok(), - content: updated.object.object_props.content_string().ok(), - cover: updated - .object - .object_props - .icon_object::() - .ok() - .and_then(|img| Media::from_activity(conn, &img).ok().map(|m| m.id)), - source: updated - .object - .ap_object_props - .source_object::() - .ok() - .map(|x| x.content), - license: updated.custom_props.license_string().ok(), - tags: updated.object.object_props.tag, - }) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for PostUpdate { type Error = Error; type Object = LicensedArticle07; @@ -1373,7 +1182,7 @@ impl AsObject for PostUpdate { fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { let mut post = - Post::from_id(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; + Post::from_id07(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; if !post.is_author(conn, actor.id)? { // TODO: maybe the author was added in the meantime @@ -1445,7 +1254,7 @@ impl AsObject07 for PostUpdate { fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { let mut post = - Post::from_id(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; + Post::from_id07(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; if !post.is_author(conn, actor.id)? { // TODO: maybe the author was added in the meantime diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index 097fb1da..89eabe71 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -1,12 +1,16 @@ use crate::{ db_conn::{DbConn, DbPool}, follows, - posts::{LicensedArticle, Post}, + posts::Post, users::{User, UserEvent}, ACTOR_SYS, CONFIG, USER_CHAN, }; -use activitypub::activity::Create; -use plume_common::activity_pub::inbox::FromId; +use activitystreams::{ + activity::{ActorAndObjectRef, Create as Create07}, + base::AnyBase, + object::kind::ArticleType, +}; +use plume_common::activity_pub::{inbox::FromId07, LicensedArticle as LicensedArticle07}; use riker::actors::{Actor, ActorFactoryArgs, ActorRefFactory, Context, Sender, Subscribe, Tell}; use std::sync::Arc; use tracing::{error, info, warn}; @@ -64,17 +68,23 @@ impl ActorFactoryArgs for RemoteFetchActor { } fn fetch_and_cache_articles(user: &Arc, conn: &DbConn) { - let create_acts = user.fetch_outbox::(); + let create_acts = user.fetch_outbox07::(); match create_acts { Ok(create_acts) => { for create_act in create_acts { - match create_act.create_props.object_object::() { - Ok(article) => { - Post::from_activity(conn, article) + match create_act + .object_field_ref() + .as_single_base() + .and_then(|base| { + let any_base = AnyBase::from_base(base.clone()); // FIXME: Don't clone() + any_base.extend::().ok() + }) { + Some(Some(article)) => { + Post::from_activity07(conn, article) .expect("Article from remote user couldn't be saved"); info!("Fetched article from remote user"); } - Err(e) => warn!("Error while fetching articles in background: {:?}", e), + _ => warn!("Error while fetching articles in background"), } } } @@ -89,7 +99,7 @@ fn fetch_and_cache_followers(user: &Arc, conn: &DbConn) { match follower_ids { Ok(user_ids) => { for user_id in user_ids { - let follower = User::from_id(conn, &user_id, None, CONFIG.proxy()); + let follower = User::from_id07(conn, &user_id, None, CONFIG.proxy()); match follower { Ok(follower) => { let inserted = follows::Follow::insert( diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 88269020..aa35aa27 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId07}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -186,46 +186,6 @@ impl AsObject07 for Post { } } -impl FromId for Reshare { - type Error = Error; - type Object = Announce; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Reshare::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, act: Announce) -> Result { - let res = Reshare::insert( - conn, - NewReshare { - post_id: Post::from_id( - conn, - &act.announce_props.object_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)? - .id, - user_id: User::from_id( - conn, - &act.announce_props.actor_link::()?, - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)? - .id, - ap_url: act.object_props.id_string()?, - }, - )?; - res.notify(conn)?; - Ok(res) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for Reshare { type Error = Error; type Object = Announce07; @@ -238,7 +198,7 @@ impl FromId07 for Reshare { let res = Reshare::insert( conn, NewReshare { - post_id: Post::from_id( + post_id: Post::from_id07( conn, act.object_field_ref() .as_single_id() @@ -249,7 +209,7 @@ impl FromId07 for Reshare { ) .map_err(|(_, e)| e)? .id, - user_id: User::from_id( + user_id: User::from_id07( conn, act.actor_field_ref() .as_single_id() diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 638d9620..3497aa99 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -13,7 +13,7 @@ use activitypub::{ }; use activitystreams::{ activity::Delete as Delete07, - actor::AsApActor, + actor::{ApActor, AsApActor}, actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, base::{AnyBase, Base}, collection::{ @@ -21,7 +21,7 @@ use activitystreams::{ }, iri_string::types::IriString, markers::Activity as Activity07, - object::{AsObject as _, Image as Image07, Tombstone as Tombstone07}, + object::{kind::ImageType, AsObject as _, Image as Image07, Tombstone as Tombstone07}, prelude::*, }; use chrono::{NaiveDateTime, Utc}; @@ -35,7 +35,7 @@ use openssl::{ }; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId07}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, @@ -53,7 +53,6 @@ use std::{ hash::{Hash, Hasher}, sync::Arc, }; -use url::Url; use webfinger::*; pub type CustomPerson = CustomObject; @@ -238,7 +237,7 @@ impl User { .into_iter() .find(|l| l.mime_type == Some(String::from("application/activity+json"))) .ok_or(Error::Webfinger)?; - User::from_id( + User::from_id07( conn, link.href.as_ref().ok_or(Error::Webfinger)?, None, @@ -256,53 +255,84 @@ impl User { .ok_or(Error::Webfinger) } - fn fetch(url: &str) -> Result { - let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; + fn fetch(url: &str) -> Result { + let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; let text = &res.text()?; // without this workaround, publicKey is not correctly deserialized - let ap_sign = serde_json::from_str::(text)?; - let mut json = serde_json::from_str::(text)?; - json.custom_props = ap_sign; + let ap_sign = serde_json::from_str::(text)?; + let person = serde_json::from_str::(text)?; + let json = CustomPerson07::new( + ApActor::new( + person + .clone() + .id_unchecked() + .ok_or(Error::MissingApProperty)? + .to_owned(), + person, + ), + ap_sign, + ); // FIXME: Don't clone() Ok(json) } pub fn fetch_from_url(conn: &DbConn, url: &str) -> Result { - User::fetch(url).and_then(|json| User::from_activity(conn, json)) + User::fetch(url).and_then(|json| User::from_activity07(conn, json)) } pub fn refetch(&self, conn: &Connection) -> Result<()> { User::fetch(&self.ap_url.clone()).and_then(|json| { let avatar = Media::save_remote( conn, - json.object - .object_props - .icon_image()? // FIXME: Fails when icon is not set - .object_props - .url_string()?, + json.ap_actor_ref() + .icon() + .ok_or(Error::MissingApProperty)? // FIXME: Fails when icon is not set + .iter() + .next() + .and_then(|i| { + i.clone() + .extend::() // FIXME: Don't clone() + .ok()? + .and_then(|url| Some(url.id_unchecked()?.to_string())) + }) + .ok_or(Error::MissingApProperty)?, self, ) .ok(); + let pub_key = &json.ext_one.public_key.public_key_pem; diesel::update(self) .set(( - users::username.eq(json.object.ap_actor_props.preferred_username_string()?), - users::display_name.eq(json.object.object_props.name_string()?), - users::outbox_url.eq(json.object.ap_actor_props.outbox_string()?), - users::inbox_url.eq(json.object.ap_actor_props.inbox_string()?), + users::username.eq(json + .ap_actor_ref() + .preferred_username() + .ok_or(Error::MissingApProperty)?), + users::display_name.eq(json + .ap_actor_ref() + .name() + .ok_or(Error::MissingApProperty)? + .to_as_string() + .ok_or(Error::MissingApProperty)?), + users::outbox_url.eq(json + .ap_actor_ref() + .outbox()? + .ok_or(Error::MissingApProperty)? + .as_str()), + users::inbox_url.eq(json.ap_actor_ref().inbox()?.as_str()), users::summary.eq(SafeString::new( &json - .object - .object_props - .summary_string() + .ap_actor_ref() + .summary() + .and_then(|summary| summary.to_as_string()) .unwrap_or_default(), )), - users::followers_endpoint.eq(json.object.ap_actor_props.followers_string()?), + users::followers_endpoint.eq(json + .ap_actor_ref() + .followers()? + .ok_or(Error::MissingApProperty)? + .as_str()), users::avatar_id.eq(avatar.map(|a| a.id)), users::last_fetched_date.eq(Utc::now().naive_utc()), - users::public_key.eq(json - .custom_props - .public_key_publickey()? - .public_key_pem_string()?), + users::public_key.eq(pub_key), )) .execute(conn) .map(|_| ()) @@ -548,7 +578,7 @@ impl User { Ok(coll) } fn fetch_outbox_page(&self, url: &str) -> Result<(Vec, Option)> { - let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; + let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; let text = &res.text()?; let json: serde_json::Value = serde_json::from_str(text)?; let items = json["items"] @@ -565,7 +595,7 @@ impl User { &self, url: &str, ) -> Result<(Vec, Option)> { - let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; + let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; let text = &res.text()?; let json: serde_json::Value = serde_json::from_str(text)?; let items = json["items"] @@ -581,7 +611,7 @@ impl User { pub fn fetch_outbox(&self) -> Result> { let mut res = get( &self.outbox_url[..], - Self::get_sender(), + Self::get_sender07(), CONFIG.proxy().cloned(), )?; let text = &res.text()?; @@ -617,7 +647,7 @@ impl User { pub fn fetch_outbox07(&self) -> Result> { let mut res = get( &self.outbox_url[..], - Self::get_sender(), + Self::get_sender07(), CONFIG.proxy().cloned(), )?; let text = &res.text()?; @@ -653,7 +683,7 @@ impl User { pub fn fetch_followers_ids(&self) -> Result> { let mut res = get( &self.followers_endpoint[..], - Self::get_sender(), + Self::get_sender07(), CONFIG.proxy().cloned(), )?; let text = &res.text()?; @@ -1097,110 +1127,6 @@ impl IntoId for User { impl Eq for User {} -impl FromId for User { - type Error = Error; - type Object = CustomPerson; - - fn from_db(conn: &DbConn, id: &str) -> Result { - Self::find_by_ap_url(conn, id) - } - - fn from_activity(conn: &DbConn, acct: CustomPerson) -> Result { - let url = Url::parse(&acct.object.object_props.id_string()?)?; - let inst = url.host_str().ok_or(Error::Url)?; - let instance = Instance::find_by_domain(conn, inst).or_else(|_| { - Instance::insert( - conn, - NewInstance { - name: inst.to_owned(), - public_domain: inst.to_owned(), - local: false, - // We don't really care about all the following for remote instances - long_description: SafeString::new(""), - short_description: SafeString::new(""), - default_license: String::new(), - open_registrations: true, - short_description_html: String::new(), - long_description_html: String::new(), - }, - ) - })?; - - let username = acct.object.ap_actor_props.preferred_username_string()?; - - if username.contains(&['<', '>', '&', '@', '\'', '"', ' ', '\t'][..]) { - return Err(Error::InvalidValue); - } - - let fqn = if instance.local { - username.clone() - } else { - format!("{}@{}", username, instance.public_domain) - }; - - let user = User::insert( - conn, - NewUser { - display_name: acct - .object - .object_props - .name_string() - .unwrap_or_else(|_| username.clone()), - username, - outbox_url: acct.object.ap_actor_props.outbox_string()?, - inbox_url: acct.object.ap_actor_props.inbox_string()?, - role: 2, - summary: acct - .object - .object_props - .summary_string() - .unwrap_or_default(), - summary_html: SafeString::new( - &acct - .object - .object_props - .summary_string() - .unwrap_or_default(), - ), - email: None, - hashed_password: None, - instance_id: instance.id, - ap_url: acct.object.object_props.id_string()?, - public_key: acct - .custom_props - .public_key_publickey()? - .public_key_pem_string()?, - private_key: None, - shared_inbox_url: acct - .object - .ap_actor_props - .endpoints_endpoint() - .and_then(|e| e.shared_inbox_string()) - .ok(), - followers_endpoint: acct.object.ap_actor_props.followers_string()?, - fqn, - avatar_id: None, - }, - )?; - - if let Ok(icon) = acct.object.object_props.icon_image() { - if let Ok(url) = icon.object_props.url_string() { - let avatar = Media::save_remote(conn, url, &user); - - if let Ok(avatar) = avatar { - user.set_avatar(conn, avatar.id)?; - } - } - } - - Ok(user) - } - - fn get_sender() -> &'static dyn Signer { - Instance::get_local_instance_user().expect("Failed to local instance user") - } -} - impl FromId07 for User { type Error = Error; type Object = CustomPerson07; @@ -1690,32 +1616,6 @@ pub(crate) mod tests { }); } - #[test] - fn self_federation() { - let conn = db(); - conn.test_transaction::<_, (), _>(|| { - let users = fill_database(&conn); - - let ap_repr = users[0].to_activity(&conn).unwrap(); - users[0].delete(&conn).unwrap(); - let user = User::from_activity(&conn, ap_repr).unwrap(); - - assert_eq!(user.username, users[0].username); - assert_eq!(user.display_name, users[0].display_name); - assert_eq!(user.outbox_url, users[0].outbox_url); - assert_eq!(user.inbox_url, users[0].inbox_url); - assert_eq!(user.instance_id, users[0].instance_id); - assert_eq!(user.ap_url, users[0].ap_url); - assert_eq!(user.public_key, users[0].public_key); - assert_eq!(user.shared_inbox_url, users[0].shared_inbox_url); - assert_eq!(user.followers_endpoint, users[0].followers_endpoint); - assert_eq!(user.avatar_url(&conn), users[0].avatar_url(&conn)); - assert_eq!(user.fqn, users[0].fqn); - assert_eq!(user.summary_html, users[0].summary_html); - Ok(()) - }); - } - #[test] fn self_federation07() { let conn = db(); diff --git a/src/inbox.rs b/src/inbox.rs index 78069b69..f4fbef47 100644 --- a/src/inbox.rs +++ b/src/inbox.rs @@ -1,5 +1,5 @@ use plume_common::activity_pub::{ - inbox::FromId, + inbox::FromId07, request::Digest, sign::{verify_http_headers, Signable}, }; @@ -26,7 +26,7 @@ pub fn handle_incoming( .or_else(|| activity["actor"]["id"].as_str()) .ok_or(status::BadRequest(Some("Missing actor id for activity")))?; - let actor = User::from_id(&conn, actor_id, None, CONFIG.proxy()) + let actor = User::from_id07(&conn, actor_id, None, CONFIG.proxy()) .expect("instance::shared_inbox: user error"); if !verify_http_headers(&actor, &headers.0, &sig).is_secure() && !act.clone().verify(&actor) { // maybe we just know an old key? diff --git a/src/routes/instance.rs b/src/routes/instance.rs index cedaa900..d0130610 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -11,7 +11,7 @@ use validator::{Validate, ValidationErrors}; use crate::inbox; use crate::routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page, RespondOrRedirect}; use crate::template_utils::{IntoContext, Ructe}; -use plume_common::activity_pub::{broadcast, inbox::FromId}; +use plume_common::activity_pub::{broadcast, inbox::FromId07}; use plume_models::{ admin::*, blocklisted_emails::*, @@ -404,7 +404,7 @@ pub fn interact(conn: DbConn, user: Option, target: String) -> Option, target: String) -> Option Date: Mon, 2 May 2022 16:07:08 +0900 Subject: [PATCH 143/233] Rename FromId07 -> FromId --- plume-common/src/activity_pub/inbox.rs | 12 ++++++------ plume-models/src/blogs.rs | 4 ++-- plume-models/src/comments.rs | 4 ++-- plume-models/src/follows.rs | 4 ++-- plume-models/src/likes.rs | 4 ++-- plume-models/src/medias.rs | 2 +- plume-models/src/posts.rs | 6 +++--- plume-models/src/remote_fetch_actor.rs | 2 +- plume-models/src/reshares.rs | 4 ++-- plume-models/src/users.rs | 4 ++-- src/inbox.rs | 2 +- src/routes/instance.rs | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 9dba803c..e08321a5 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -199,9 +199,9 @@ where /// Registers an handler on this Inbox. pub fn with07(self, proxy: Option<&reqwest::Proxy>) -> Self where - A: AsActor<&'a C> + FromId07, + A: AsActor<&'a C> + FromId, V: activitystreams::markers::Activity + serde::de::DeserializeOwned, - M: AsObject07 + FromId07, + M: AsObject07 + FromId, M::Output: Into, { if let Self::NotHandled(ctx, mut act, e) = self { @@ -328,7 +328,7 @@ fn get_id(json: serde_json::Value) -> Option { /// a full object, and if so, save it with `from_activity`. If it is only an ID, it will try to find /// it in the database with `from_db`, and otherwise dereference (fetch) the full object and parse it /// with `from_activity`. -pub trait FromId07: Sized { +pub trait FromId: Sized { /// The type representing a failure type Error: From> + Debug; @@ -742,7 +742,7 @@ mod tests { } struct MyActor; - impl FromId07<()> for MyActor { + impl FromId<()> for MyActor { type Error = (); type Object = Person07; @@ -811,7 +811,7 @@ mod tests { } struct MyObject07; - impl FromId07<()> for MyObject07 { + impl FromId<()> for MyObject07 { type Error = (); type Object = Note07; @@ -977,7 +977,7 @@ mod tests { } } - impl FromId07<()> for FailingActor { + impl FromId<()> for FailingActor { type Error = (); type Object = Person07; diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 2de2e6ed..a48e9fbf 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -27,7 +27,7 @@ use openssl::{ sign::{Signer, Verifier}, }; use plume_common::activity_pub::{ - inbox::{AsActor, FromId07}, + inbox::{AsActor, FromId}, sign, ActivityStream, ApSignature, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, PublicKey, PublicKey07, Source, SourceProperty, ToAsString, ToAsUri, }; @@ -470,7 +470,7 @@ impl IntoId for Blog { } } -impl FromId07 for Blog { +impl FromId for Blog { type Error = Error; type Object = CustomGroup07; diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 31df688b..cd28113e 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -30,7 +30,7 @@ use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -294,7 +294,7 @@ impl Comment { } } -impl FromId07 for Comment { +impl FromId for Comment { type Error = Error; type Object = Note07; diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 6a2f3a9a..36c24fa7 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -12,7 +12,7 @@ use activitystreams::{ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, broadcast07, - inbox::{AsActor, AsObject, AsObject07, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -272,7 +272,7 @@ impl AsObject07 for User { } } -impl FromId07 for Follow { +impl FromId for Follow { type Error = Error; type Object = FollowAct07; diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 8a7b0e23..a4959978 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -158,7 +158,7 @@ impl AsObject07 for Post { } } -impl FromId07 for Like { +impl FromId for Like { type Error = Error; type Object = Like07; diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 13048292..2837a69f 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -7,7 +7,7 @@ use activitystreams::{object::Image as Image07, prelude::*}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use guid_create::GUID; use plume_common::{ - activity_pub::{inbox::FromId07, request, Id, ToAsString, ToAsUri}, + activity_pub::{inbox::FromId, request, Id, ToAsString, ToAsUri}, utils::{escape, MediaProcessor}, }; use std::{ diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index ad5bbebe..1a2b5520 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -26,7 +26,7 @@ use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Hashtag, Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, @@ -863,7 +863,7 @@ impl Post { } } -impl FromId07 for Post { +impl FromId for Post { type Error = Error; type Object = LicensedArticle07; @@ -1119,7 +1119,7 @@ pub struct PostUpdate { pub tags: Option, } -impl FromId07 for PostUpdate { +impl FromId for PostUpdate { type Error = Error; type Object = LicensedArticle07; diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index 89eabe71..b91be1bf 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -10,7 +10,7 @@ use activitystreams::{ base::AnyBase, object::kind::ArticleType, }; -use plume_common::activity_pub::{inbox::FromId07, LicensedArticle as LicensedArticle07}; +use plume_common::activity_pub::{inbox::FromId, LicensedArticle as LicensedArticle07}; use riker::actors::{Actor, ActorFactoryArgs, ActorRefFactory, Context, Sender, Subscribe, Tell}; use std::sync::Arc; use tracing::{error, info, warn}; diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index aa35aa27..bfd89575 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -186,7 +186,7 @@ impl AsObject07 for Post { } } -impl FromId07 for Reshare { +impl FromId for Reshare { type Error = Error; type Object = Announce07; diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 3497aa99..fa20fb71 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -35,7 +35,7 @@ use openssl::{ }; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId07}, + inbox::{AsActor, AsObject, AsObject07, FromId}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, @@ -1127,7 +1127,7 @@ impl IntoId for User { impl Eq for User {} -impl FromId07 for User { +impl FromId for User { type Error = Error; type Object = CustomPerson07; diff --git a/src/inbox.rs b/src/inbox.rs index f4fbef47..d9498db8 100644 --- a/src/inbox.rs +++ b/src/inbox.rs @@ -1,5 +1,5 @@ use plume_common::activity_pub::{ - inbox::FromId07, + inbox::FromId, request::Digest, sign::{verify_http_headers, Signable}, }; diff --git a/src/routes/instance.rs b/src/routes/instance.rs index d0130610..5c980ea9 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -11,7 +11,7 @@ use validator::{Validate, ValidationErrors}; use crate::inbox; use crate::routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page, RespondOrRedirect}; use crate::template_utils::{IntoContext, Ructe}; -use plume_common::activity_pub::{broadcast, inbox::FromId07}; +use plume_common::activity_pub::{broadcast, inbox::FromId}; use plume_models::{ admin::*, blocklisted_emails::*, From 33afe9111edcdb351f2b4428387fb99da716ab7f Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 17:38:08 +0900 Subject: [PATCH 144/233] Remove AsObject --- plume-common/src/activity_pub/inbox.rs | 196 ------------------------- plume-models/src/comments.rs | 41 +----- plume-models/src/follows.rs | 39 +---- plume-models/src/likes.rs | 41 +----- plume-models/src/posts.rs | 101 +------------ plume-models/src/reshares.rs | 43 +----- plume-models/src/users.rs | 15 +- 7 files changed, 6 insertions(+), 470 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index e08321a5..be28eac2 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -519,146 +519,6 @@ pub trait AsActor { /// } /// } /// ``` -pub trait AsObject -where - V: activitypub::Activity, -{ - /// What kind of error is returned when something fails - type Error; - - /// What is returned by `AsObject::activity`, if anything is returned - type Output = (); - - /// Handle a specific type of activity dealing with this type of objects. - /// - /// The implementations should check that the actor is actually authorized - /// to perform this action. - /// - /// # Parameters - /// - /// - `self`: the object on which the activity acts - /// - `ctx`: the context passed to `Inbox::handle` - /// - `actor`: the actor who did this activity - /// - `id`: the ID of this activity - fn activity(self, ctx: C, actor: A, id: &str) -> Result; -} - -/// Should be implemented by anything representing an ActivityPub object. -/// -/// # Type parameters -/// -/// - `A`: the actor type -/// - `V`: the ActivityPub verb/activity -/// - `O`: the ActivityPub type of the Object for this activity (usually the type corresponding to `Self`) -/// - `C`: the context needed to handle the activity (usually a database connection) -/// -/// # Example -/// -/// An implementation of AsObject that handles Note creation by an Account model, -/// representing the Note by a Message type, without any specific context. -/// -/// ```rust -/// # extern crate activitypub; -/// # use activitypub::{activity::Create, actor::Person, object::Note}; -/// # use plume_common::activity_pub::inbox::{AsActor, AsObject, FromId}; -/// # use plume_common::activity_pub::sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}; -/// # use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa}; -/// # use once_cell::sync::Lazy; -/// # -/// # static MY_SIGNER: Lazy = Lazy::new(|| MySigner::new()); -/// # -/// # struct MySigner { -/// # public_key: String, -/// # private_key: String, -/// # } -/// # -/// # impl MySigner { -/// # fn new() -> Self { -/// # let (pub_key, priv_key) = gen_keypair(); -/// # Self { -/// # public_key: String::from_utf8(pub_key).unwrap(), -/// # private_key: String::from_utf8(priv_key).unwrap(), -/// # } -/// # } -/// # } -/// # -/// # impl Signer for MySigner { -/// # fn get_key_id(&self) -> String { -/// # "mysigner".into() -/// # } -/// # -/// # fn sign(&self, to_sign: &str) -> SignResult> { -/// # let key = PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.as_ref()).unwrap()) -/// # .unwrap(); -/// # let mut signer = openssl::sign::Signer::new(MessageDigest::sha256(), &key).unwrap(); -/// # signer.update(to_sign.as_bytes()).unwrap(); -/// # signer.sign_to_vec().map_err(|_| SignError()) -/// # } -/// # -/// # fn verify(&self, data: &str, signature: &[u8]) -> SignResult { -/// # let key = PKey::from_rsa(Rsa::public_key_from_pem(self.public_key.as_ref()).unwrap()) -/// # .unwrap(); -/// # let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha256(), &key).unwrap(); -/// # verifier.update(data.as_bytes()).unwrap(); -/// # verifier.verify(&signature).map_err(|_| SignError()) -/// # } -/// # } -/// # -/// # struct Account; -/// # impl FromId<()> for Account { -/// # type Error = (); -/// # type Object = Person; -/// # -/// # fn from_db(_: &(), _id: &str) -> Result { -/// # Ok(Account) -/// # } -/// # -/// # fn from_activity(_: &(), obj: Person) -> Result { -/// # Ok(Account) -/// # } -/// # -/// # fn get_sender() -> &'static dyn Signer { -/// # &*MY_SIGNER -/// # } -/// # } -/// # impl AsActor<()> for Account { -/// # fn get_inbox_url(&self) -> String { -/// # String::new() -/// # } -/// # fn is_local(&self) -> bool { false } -/// # } -/// #[derive(Debug)] -/// struct Message { -/// text: String, -/// } -/// -/// impl FromId<()> for Message { -/// type Error = (); -/// type Object = Note; -/// -/// fn from_db(_: &(), _id: &str) -> Result { -/// Ok(Message { text: "From DB".into() }) -/// } -/// -/// fn from_activity(_: &(), obj: Note) -> Result { -/// Ok(Message { text: obj.object_props.content_string().map_err(|_| ())? }) -/// } -/// -/// fn get_sender() -> &'static dyn Signer { -/// &*MY_SIGNER -/// } -/// } -/// -/// impl AsObject for Message { -/// type Error = (); -/// type Output = (); -/// -/// fn activity(self, _: (), _actor: Account, _id: &str) -> Result<(), ()> { -/// println!("New Note: {:?}", self); -/// Ok(()) -/// } -/// } -/// ``` pub trait AsObject07 where V: activitystreams::markers::Activity, @@ -769,47 +629,6 @@ mod tests { } } - struct MyObject; - impl AsObject for MyObject { - type Error = (); - type Output = (); - - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { - println!("MyActor is creating a Note"); - Ok(()) - } - } - - impl AsObject for MyObject { - type Error = (); - type Output = (); - - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { - println!("MyActor is liking a Note"); - Ok(()) - } - } - - impl AsObject for MyObject { - type Error = (); - type Output = (); - - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { - println!("MyActor is deleting a Note"); - Ok(()) - } - } - - impl AsObject for MyObject { - type Error = (); - type Output = (); - - fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { - println!("MyActor is announcing a Note"); - Ok(()) - } - } - struct MyObject07; impl FromId<()> for MyObject07 { type Error = (); @@ -962,21 +781,6 @@ mod tests { } } - impl AsObject for MyObject { - type Error = (); - type Output = (); - - fn activity( - self, - _: &(), - _actor: FailingActor, - _id: &str, - ) -> Result { - println!("FailingActor is creating a Note"); - Ok(()) - } - } - impl FromId<()> for FailingActor { type Error = (); type Object = Person07; diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index cd28113e..7c2864ce 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -30,7 +30,7 @@ use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject07, FromId}, sign::Signer, Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -431,45 +431,6 @@ impl FromId for Comment { } } -impl AsObject for Comment { - type Error = Error; - type Output = Self; - - fn activity(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { - // The actual creation takes place in the FromId impl - Ok(self) - } -} - -impl AsObject for Comment { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - if self.author_id != actor.id { - return Err(Error::Unauthorized); - } - - for m in Mention::list_for_comment(conn, self.id)? { - for n in Notification::find_for_mention(conn, &m)? { - n.delete(conn)?; - } - m.delete(conn)?; - } - - for n in Notification::find_for_comment(conn, &self)? { - n.delete(&**conn)?; - } - - diesel::update(comments::table) - .filter(comments::in_response_to_id.eq(self.id)) - .set(comments::in_response_to_id.eq(self.in_response_to_id)) - .execute(&**conn)?; - diesel::delete(&self).execute(&**conn)?; - Ok(()) - } -} - impl AsObject07 for Comment { type Error = Error; type Output = Self; diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 36c24fa7..a4094802 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -12,7 +12,7 @@ use activitystreams::{ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, broadcast07, - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -242,22 +242,6 @@ impl Follow { } } -impl AsObject for User { - type Error = Error; - type Output = Follow; - - fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { - // Mastodon (at least) requires the full Follow object when accepting it, - // so we rebuilt it here - let mut follow = FollowAct::default(); - follow.object_props.set_id_string(id.to_string())?; - follow - .follow_props - .set_actor_link::(actor.clone().into_id())?; - Follow::accept_follow(conn, &actor, &self, follow, actor.id, self.id) - } -} - impl AsObject07 for User { type Error = Error; type Output = Follow; @@ -312,27 +296,6 @@ impl FromId for Follow { } } -impl AsObject for Follow { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - let conn = conn; - if self.follower_id == actor.id { - diesel::delete(&self).execute(&**conn)?; - - // delete associated notification if any - if let Ok(notif) = Notification::find(conn, notification_kind::FOLLOW, self.id) { - diesel::delete(¬if).execute(&**conn)?; - } - - Ok(()) - } else { - Err(Error::Unauthorized) - } - } -} - impl AsObject07 for Follow { type Error = Error; type Output = (); diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index a4959978..07760edf 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -118,26 +118,6 @@ impl Like { } } -impl AsObject for Post { - type Error = Error; - type Output = Like; - - fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { - let res = Like::insert( - conn, - NewLike { - post_id: self.id, - user_id: actor.id, - ap_url: id.to_string(), - }, - )?; - res.notify(conn)?; - - Timeline::add_to_all_timelines(conn, &self, Kind::Like(&actor))?; - Ok(res) - } -} - impl AsObject07 for Post { type Error = Error; type Output = Like; @@ -207,25 +187,6 @@ impl FromId for Like { } } -impl AsObject for Like { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - if actor.id == self.user_id { - diesel::delete(&self).execute(&**conn)?; - - // delete associated notification if any - if let Ok(notif) = Notification::find(conn, notification_kind::LIKE, self.id) { - diesel::delete(¬if).execute(&**conn)?; - } - Ok(()) - } else { - Err(Error::Unauthorized) - } - } -} - impl AsObject07 for Like { type Error = Error; type Output = (); diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 1a2b5520..4cd6c648 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -26,7 +26,7 @@ use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject07, FromId}, sign::Signer, Hashtag, Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, @@ -1054,16 +1054,6 @@ impl FromId for Post { } } -impl AsObject for Post { - type Error = Error; - type Output = Post; - - fn activity(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { - // TODO: check that _actor is actually one of the author? - Ok(self) - } -} - impl AsObject07 for Post { type Error = Error; type Output = Self; @@ -1074,23 +1064,6 @@ impl AsObject07 for Post { } } -impl AsObject for Post { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - let can_delete = self - .get_authors(conn)? - .into_iter() - .any(|a| actor.id == a.id); - if can_delete { - self.delete(conn).map(|_| ()) - } else { - Err(Error::Unauthorized) - } - } -} - impl AsObject07 for Post { type Error = Error; type Output = (); @@ -1176,78 +1149,6 @@ impl FromId for PostUpdate { } } -impl AsObject for PostUpdate { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - let mut post = - Post::from_id07(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; - - if !post.is_author(conn, actor.id)? { - // TODO: maybe the author was added in the meantime - return Err(Error::Unauthorized); - } - - if let Some(title) = self.title { - post.slug = Post::slug(&title).to_string(); - post.title = title; - } - - if let Some(content) = self.content { - post.content = SafeString::new(&content); - } - - if let Some(subtitle) = self.subtitle { - post.subtitle = subtitle; - } - - post.cover_id = self.cover; - - if let Some(source) = self.source { - post.source = source; - } - - if let Some(license) = self.license { - post.license = license; - } - - let mut txt_hashtags = md_to_html(&post.source, None, false, None) - .2 - .into_iter() - .collect::>(); - if let Some(serde_json::Value::Array(mention_tags)) = self.tags { - let mut mentions = vec![]; - let mut tags = vec![]; - let mut hashtags = vec![]; - for tag in mention_tags { - serde_json::from_value::(tag.clone()) - .map(|m| mentions.push(m)) - .ok(); - - serde_json::from_value::(tag.clone()) - .map_err(Error::from) - .and_then(|t| { - let tag_name = t.name_string()?; - if txt_hashtags.remove(&tag_name) { - hashtags.push(t); - } else { - tags.push(t); - } - Ok(()) - }) - .ok(); - } - post.update_mentions(conn, mentions)?; - post.update_tags(conn, tags)?; - post.update_hashtags(conn, hashtags)?; - } - - post.update(conn)?; - Ok(()) - } -} - impl AsObject07 for PostUpdate { type Error = Error; type Output = (); diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index bfd89575..419e19d3 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject07, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -144,27 +144,6 @@ impl Reshare { } } -impl AsObject for Post { - type Error = Error; - type Output = Reshare; - - fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { - let conn = conn; - let reshare = Reshare::insert( - conn, - NewReshare { - post_id: self.id, - user_id: actor.id, - ap_url: id.to_string(), - }, - )?; - reshare.notify(conn)?; - - Timeline::add_to_all_timelines(conn, &self, Kind::Reshare(&actor))?; - Ok(reshare) - } -} - impl AsObject07 for Post { type Error = Error; type Output = Reshare; @@ -235,26 +214,6 @@ impl FromId for Reshare { } } -impl AsObject for Reshare { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - if actor.id == self.user_id { - diesel::delete(&self).execute(&**conn)?; - - // delete associated notification if any - if let Ok(notif) = Notification::find(conn, notification_kind::RESHARE, self.id) { - diesel::delete(¬if).execute(&**conn)?; - } - - Ok(()) - } else { - Err(Error::Unauthorized) - } - } -} - impl AsObject07 for Reshare { type Error = Error; type Output = (); diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index fa20fb71..09345c98 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -35,7 +35,7 @@ use openssl::{ }; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject, AsObject07, FromId}, + inbox::{AsActor, AsObject07, FromId}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, @@ -1248,19 +1248,6 @@ impl AsActor<&DbConn> for User { } } -impl AsObject for User { - type Error = Error; - type Output = (); - - fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { - if self.id == actor.id { - self.delete(conn).map(|_| ()) - } else { - Err(Error::Unauthorized) - } - } -} - impl AsObject07 for User { type Error = Error; type Output = (); From 0ab7774e290ca919859e11215da680805383d921 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 17:43:03 +0900 Subject: [PATCH 145/233] Rename: AsObject07 -> AsObject --- plume-common/src/activity_pub/inbox.rs | 14 +++++++------- plume-models/src/comments.rs | 6 +++--- plume-models/src/follows.rs | 6 +++--- plume-models/src/likes.rs | 6 +++--- plume-models/src/posts.rs | 8 ++++---- plume-models/src/reshares.rs | 6 +++--- plume-models/src/users.rs | 4 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index be28eac2..4751588f 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -201,7 +201,7 @@ where where A: AsActor<&'a C> + FromId, V: activitystreams::markers::Activity + serde::de::DeserializeOwned, - M: AsObject07 + FromId, + M: AsObject + FromId, M::Output: Into, { if let Self::NotHandled(ctx, mut act, e) = self { @@ -519,7 +519,7 @@ pub trait AsActor { /// } /// } /// ``` -pub trait AsObject07 +pub trait AsObject where V: activitystreams::markers::Activity, { @@ -646,7 +646,7 @@ mod tests { &*MY_SIGNER } } - impl AsObject07 for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -661,7 +661,7 @@ mod tests { } } - impl AsObject07 for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -676,7 +676,7 @@ mod tests { } } - impl AsObject07 for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -691,7 +691,7 @@ mod tests { } } - impl AsObject07 for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -798,7 +798,7 @@ mod tests { } } - impl AsObject07 for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 7c2864ce..e37273c4 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -30,7 +30,7 @@ use chrono::{self, NaiveDateTime, TimeZone, Utc}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject07, FromId}, + inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -431,7 +431,7 @@ impl FromId for Comment { } } -impl AsObject07 for Comment { +impl AsObject for Comment { type Error = Error; type Output = Self; @@ -441,7 +441,7 @@ impl AsObject07 for Comment { } } -impl AsObject07 for Comment { +impl AsObject for Comment { type Error = Error; type Output = (); diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index a4094802..6876328a 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -12,7 +12,7 @@ use activitystreams::{ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ broadcast, broadcast07, - inbox::{AsActor, AsObject07, FromId}, + inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -242,7 +242,7 @@ impl Follow { } } -impl AsObject07 for User { +impl AsObject for User { type Error = Error; type Output = Follow; @@ -296,7 +296,7 @@ impl FromId for Follow { } } -impl AsObject07 for Follow { +impl AsObject for Follow { type Error = Error; type Output = (); diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 07760edf..59a0d6bf 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject07, FromId}, + inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -118,7 +118,7 @@ impl Like { } } -impl AsObject07 for Post { +impl AsObject for Post { type Error = Error; type Output = Like; @@ -187,7 +187,7 @@ impl FromId for Like { } } -impl AsObject07 for Like { +impl AsObject for Like { type Error = Error; type Output = (); diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 4cd6c648..267fa925 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -26,7 +26,7 @@ use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject07, FromId}, + inbox::{AsActor, AsObject, FromId}, sign::Signer, Hashtag, Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, @@ -1054,7 +1054,7 @@ impl FromId for Post { } } -impl AsObject07 for Post { +impl AsObject for Post { type Error = Error; type Output = Self; @@ -1064,7 +1064,7 @@ impl AsObject07 for Post { } } -impl AsObject07 for Post { +impl AsObject for Post { type Error = Error; type Output = (); @@ -1149,7 +1149,7 @@ impl FromId for PostUpdate { } } -impl AsObject07 for PostUpdate { +impl AsObject for PostUpdate { type Error = Error; type Output = (); diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 419e19d3..1e023cd4 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -12,7 +12,7 @@ use activitystreams::{ use chrono::NaiveDateTime; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ - inbox::{AsActor, AsObject07, FromId}, + inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, }; @@ -144,7 +144,7 @@ impl Reshare { } } -impl AsObject07 for Post { +impl AsObject for Post { type Error = Error; type Output = Reshare; @@ -214,7 +214,7 @@ impl FromId for Reshare { } } -impl AsObject07 for Reshare { +impl AsObject for Reshare { type Error = Error; type Output = (); diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 09345c98..e224b553 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -35,7 +35,7 @@ use openssl::{ }; use plume_common::{ activity_pub::{ - inbox::{AsActor, AsObject07, FromId}, + inbox::{AsActor, AsObject, FromId}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, @@ -1248,7 +1248,7 @@ impl AsActor<&DbConn> for User { } } -impl AsObject07 for User { +impl AsObject for User { type Error = Error; type Output = (); From 28440271bb752b38a29dbd0fdeecec49ff1ead6c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 19:24:36 +0900 Subject: [PATCH 146/233] Rename: FromId::from_id07 -> from_id --- plume-common/src/activity_pub/inbox.rs | 6 +++--- plume-models/src/blogs.rs | 6 +++--- plume-models/src/comments.rs | 4 ++-- plume-models/src/follows.rs | 4 ++-- plume-models/src/likes.rs | 4 ++-- plume-models/src/medias.rs | 4 ++-- plume-models/src/posts.rs | 6 +++--- plume-models/src/remote_fetch_actor.rs | 2 +- plume-models/src/reshares.rs | 4 ++-- plume-models/src/users.rs | 2 +- src/inbox.rs | 2 +- src/routes/instance.rs | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 4751588f..1bc886c3 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -223,7 +223,7 @@ where } // Transform this actor to a model (see FromId for details about the from_id function) - let actor = match A::from_id07( + let actor = match A::from_id( ctx, &actor_id, serde_json::from_value(act["actor"].clone()).ok(), @@ -244,7 +244,7 @@ where Some(x) => x, None => return Self::NotHandled(ctx, act, InboxError::InvalidObject(None)), }; - let obj = match M::from_id07( + let obj = match M::from_id( ctx, &obj_id, serde_json::from_value(act["object"].clone()).ok(), @@ -343,7 +343,7 @@ pub trait FromId: Sized { /// - `id`: the ActivityPub ID of the object to find /// - `object`: optional object that will be used if the object was not found in the database /// If absent, the ID will be dereferenced. - fn from_id07( + fn from_id( ctx: &C, id: &str, object: Option, diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index a48e9fbf..17f0eadb 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -160,7 +160,7 @@ impl Blog { .find(|l| l.mime_type == Some(String::from("application/activity+json"))) .ok_or(Error::Webfinger) .and_then(|l| { - Blog::from_id07( + Blog::from_id( conn, &l.href.ok_or(Error::MissingApProperty)?, None, @@ -526,7 +526,7 @@ impl FromId for Blog { Media::save_remote( conn, icon.url()?.to_as_uri()?, - &User::from_id07(conn, &owner, None, CONFIG.proxy()).ok()?, + &User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?, ) .ok() }) @@ -543,7 +543,7 @@ impl FromId for Blog { Media::save_remote( conn, banner.url()?.to_as_uri()?, - &User::from_id07(conn, &owner, None, CONFIG.proxy()).ok()?, + &User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?, ) .ok() }) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index e37273c4..d4a9bd61 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -349,7 +349,7 @@ impl FromId for Comment { post_id: previous_comment.map(|c| c.post_id).or_else(|_| { Ok(Post::find_by_ap_url(conn, previous_url.as_str())?.id) as Result })?, - author_id: User::from_id07( + author_id: User::from_id( conn, ¬e .attributed_to() @@ -402,7 +402,7 @@ impl FromId for Comment { let receivers_ap_url = receiver_ids .into_iter() .flat_map(|v| { - if let Ok(user) = User::from_id07(conn, v.as_ref(), None, CONFIG.proxy()) { + if let Ok(user) = User::from_id(conn, v.as_ref(), None, CONFIG.proxy()) { vec![user] } else { vec![] // TODO try to fetch collection diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 6876328a..9bc2d93f 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -265,7 +265,7 @@ impl FromId for Follow { } fn from_activity07(conn: &DbConn, follow: FollowAct07) -> Result { - let actor = User::from_id07( + let actor = User::from_id( conn, follow .actor_field_ref() @@ -277,7 +277,7 @@ impl FromId for Follow { ) .map_err(|(_, e)| e)?; - let target = User::from_id07( + let target = User::from_id( conn, follow .object_field_ref() diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 59a0d6bf..0be2164b 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -150,7 +150,7 @@ impl FromId for Like { let res = Like::insert( conn, NewLike { - post_id: Post::from_id07( + post_id: Post::from_id( conn, act.object_field_ref() .as_single_id() @@ -161,7 +161,7 @@ impl FromId for Like { ) .map_err(|(_, e)| e)? .id, - user_id: User::from_id07( + user_id: User::from_id( conn, act.actor_field_ref() .as_single_id() diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 2837a69f..6796170c 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -275,7 +275,7 @@ impl Media { remote_url: None, sensitive: image.object_props.summary_string().is_ok(), content_warning: image.object_props.summary_string().ok(), - owner_id: User::from_id07( + owner_id: User::from_id( conn, image .object_props @@ -362,7 +362,7 @@ impl Media { remote_url: None, sensitive: summary.is_some(), content_warning: summary, - owner_id: User::from_id07( + owner_id: User::from_id( conn, &image .attributed_to() diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 267fa925..7a58c328 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -883,14 +883,14 @@ impl FromId for Post { .iter() .fold((None, vec![]), |(blog, mut authors), link| { if let Some(url) = link.id() { - match User::from_id07(conn, url.as_str(), None, CONFIG.proxy()) { + match User::from_id(conn, url.as_str(), None, CONFIG.proxy()) { Ok(u) => { authors.push(u); (blog, authors) } Err(_) => ( blog.or_else(|| { - Blog::from_id07(conn, url.as_str(), None, CONFIG.proxy()).ok() + Blog::from_id(conn, url.as_str(), None, CONFIG.proxy()).ok() }), authors, ), @@ -1155,7 +1155,7 @@ impl AsObject for PostUpdate { fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { let mut post = - Post::from_id07(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; + Post::from_id(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; if !post.is_author(conn, actor.id)? { // TODO: maybe the author was added in the meantime diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index b91be1bf..83d87b85 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -99,7 +99,7 @@ fn fetch_and_cache_followers(user: &Arc, conn: &DbConn) { match follower_ids { Ok(user_ids) => { for user_id in user_ids { - let follower = User::from_id07(conn, &user_id, None, CONFIG.proxy()); + let follower = User::from_id(conn, &user_id, None, CONFIG.proxy()); match follower { Ok(follower) => { let inserted = follows::Follow::insert( diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 1e023cd4..05973f89 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -177,7 +177,7 @@ impl FromId for Reshare { let res = Reshare::insert( conn, NewReshare { - post_id: Post::from_id07( + post_id: Post::from_id( conn, act.object_field_ref() .as_single_id() @@ -188,7 +188,7 @@ impl FromId for Reshare { ) .map_err(|(_, e)| e)? .id, - user_id: User::from_id07( + user_id: User::from_id( conn, act.actor_field_ref() .as_single_id() diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index e224b553..69eb1dd0 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -237,7 +237,7 @@ impl User { .into_iter() .find(|l| l.mime_type == Some(String::from("application/activity+json"))) .ok_or(Error::Webfinger)?; - User::from_id07( + User::from_id( conn, link.href.as_ref().ok_or(Error::Webfinger)?, None, diff --git a/src/inbox.rs b/src/inbox.rs index d9498db8..78069b69 100644 --- a/src/inbox.rs +++ b/src/inbox.rs @@ -26,7 +26,7 @@ pub fn handle_incoming( .or_else(|| activity["actor"]["id"].as_str()) .ok_or(status::BadRequest(Some("Missing actor id for activity")))?; - let actor = User::from_id07(&conn, actor_id, None, CONFIG.proxy()) + let actor = User::from_id(&conn, actor_id, None, CONFIG.proxy()) .expect("instance::shared_inbox: user error"); if !verify_http_headers(&actor, &headers.0, &sig).is_secure() && !act.clone().verify(&actor) { // maybe we just know an old key? diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 5c980ea9..cedaa900 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -404,7 +404,7 @@ pub fn interact(conn: DbConn, user: Option, target: String) -> Option, target: String) -> Option Date: Mon, 2 May 2022 21:00:44 +0900 Subject: [PATCH 147/233] Add test for Tag::from_activity07() --- plume-models/src/tags.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index 7631358b..c41700c9 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -165,6 +165,24 @@ mod tests { }); } + #[test] + fn from_activity07() { + let conn = &db(); + conn.test_transaction::<_, Error, _>(|| { + let (posts, _users, _blogs) = fill_database(conn); + let post_id = posts[0].id; + let mut ht = Hashtag07::new(); + ht.set_href(ap_url(&format!("https://plu.me/tag/a_tag")).parse::()?); + ht.set_name("a_tag".to_string()); + let tag = Tag::from_activity07(conn, &ht, post_id, true)?; + + assert_eq!(&tag.tag, "a_tag"); + assert!(tag.is_hashtag); + + Ok(()) + }); + } + #[test] fn build_activity() { let conn = &db(); From 39b49c707e12d43b53e1c2c0c5ab4c8e17c5c101 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 21:49:00 +0900 Subject: [PATCH 148/233] Use Post::update_mentions07() instead of update_mentions() --- plume-models/src/posts.rs | 59 ++++++++------------------------------- src/routes/posts.rs | 4 +-- 2 files changed, 13 insertions(+), 50 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 7a58c328..896cb65a 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -5,7 +5,6 @@ use crate::{ }; use activitypub::{ activity::{Create, Delete, Update}, - link, object::{Article, Image, Tombstone}, CustomObject, }; @@ -560,46 +559,6 @@ impl Post { Ok(act) } - pub fn update_mentions(&self, conn: &Connection, mentions: Vec) -> Result<()> { - let mentions = mentions - .into_iter() - .map(|m| { - ( - m.link_props - .href_string() - .ok() - .and_then(|ap_url| User::find_by_ap_url(conn, &ap_url).ok()) - .map(|u| u.id), - m, - ) - }) - .filter_map(|(id, m)| id.map(|id| (m, id))) - .collect::>(); - - let old_mentions = Mention::list_for_post(conn, self.id)?; - let old_user_mentioned = old_mentions - .iter() - .map(|m| m.mentioned_id) - .collect::>(); - for (m, id) in &mentions { - if !old_user_mentioned.contains(id) { - Mention::from_activity(&*conn, m, self.id, true, true)?; - } - } - - let new_mentions = mentions - .into_iter() - .map(|(_m, id)| id) - .collect::>(); - for m in old_mentions - .iter() - .filter(|m| !new_mentions.contains(&m.mentioned_id)) - { - m.delete(conn)?; - } - Ok(()) - } - pub fn update_mentions07( &self, conn: &Connection, @@ -1194,15 +1153,19 @@ impl AsObject for PostUpdate { let mut tags = vec![]; let mut hashtags = vec![]; for tag in mention_tags { - serde_json::from_value::(tag.clone()) + serde_json::from_value::(tag.clone()) .map(|m| mentions.push(m)) .ok(); - serde_json::from_value::(tag.clone()) + serde_json::from_value::(tag.clone()) .map_err(Error::from) .and_then(|t| { - let tag_name = t.name_string()?; - if txt_hashtags.remove(&tag_name) { + let tag_name = t.name.as_ref().ok_or(Error::MissingApProperty)?; + let tag_name_str = tag_name + .as_xsd_string() + .or_else(|| tag_name.as_rdf_lang_string().map(|rls| &*rls.value)) + .ok_or(Error::MissingApProperty)?; + if txt_hashtags.remove(tag_name_str) { hashtags.push(t); } else { tags.push(t); @@ -1211,9 +1174,9 @@ impl AsObject for PostUpdate { }) .ok(); } - post.update_mentions(conn, mentions)?; - post.update_tags(conn, tags)?; - post.update_hashtags(conn, hashtags)?; + post.update_mentions07(conn, mentions)?; + post.update_tags07(conn, tags)?; + post.update_hashtags07(conn, hashtags)?; } post.update(conn)?; diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 854a5621..da48016f 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -306,11 +306,11 @@ pub fn update( post.update(&conn).expect("post::update: update error"); if post.published { - post.update_mentions( + post.update_mentions07( &conn, mentions .into_iter() - .filter_map(|m| Mention::build_activity(&conn, &m).ok()) + .filter_map(|m| Mention::build_activity07(&conn, &m).ok()) .collect(), ) .expect("post::update: mentions error"); From a589435f4f978b6ca2d8e6f4c67c0ab0c84f679b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:19:00 +0900 Subject: [PATCH 149/233] Use Post::create_activity07() instead of create_activity() --- plume-common/src/activity_pub/mod.rs | 2 +- plume-models/src/posts.rs | 112 +-------------------------- plume-models/src/users.rs | 2 +- src/routes/posts.rs | 20 ++--- 4 files changed, 14 insertions(+), 122 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index af74dd31..5edab856 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -74,7 +74,7 @@ impl ActivityStream { } } -impl<'r, O: Object> Responder<'r> for ActivityStream { +impl<'r, O: serde::Serialize> Responder<'r> for ActivityStream { fn respond_to(self, request: &Request<'_>) -> Result, Status> { let mut json = serde_json::to_value(&self.0).map_err(|_| Status::InternalServerError)?; json["@context"] = context(); diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 896cb65a..3ffec9b1 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -4,7 +4,7 @@ use crate::{ Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN, }; use activitypub::{ - activity::{Create, Delete, Update}, + activity::{Delete, Update}, object::{Article, Image, Tombstone}, CustomObject, }; @@ -496,21 +496,6 @@ impl Post { Ok(LicensedArticle07::new(article, license, source)) } - pub fn create_activity(&self, conn: &Connection) -> Result { - let article = self.to_activity(conn)?; - let mut act = Create::default(); - act.object_props - .set_id_string(format!("{}/activity", self.ap_url))?; - act.object_props - .set_to_link_vec::(article.object.object_props.to_link_vec()?)?; - act.object_props - .set_cc_link_vec::(article.object.object_props.cc_link_vec()?)?; - act.create_props - .set_actor_link(Id::new(self.get_authors(conn)?[0].clone().ap_url))?; - act.create_props.set_object_object(article)?; - Ok(act) - } - pub fn create_activity07(&self, conn: &Connection) -> Result { let article = self.to_activity07(conn)?; let to = article.to().ok_or(Error::MissingApProperty)?.clone(); @@ -1236,56 +1221,6 @@ mod tests { (post.to_owned(), mention.to_owned(), posts, users, blogs) } - // creates a post, get it's Create activity, delete the post, - // "send" the Create to the inbox, and check it works - #[test] - fn self_federation() { - let conn = &db(); - conn.test_transaction::<_, (), _>(|| { - let (_, users, blogs) = fill_database(&conn); - let post = Post::insert( - &conn, - NewPost { - blog_id: blogs[0].id, - slug: "yo".into(), - title: "Yo".into(), - content: SafeString::new("Hello"), - published: true, - license: "WTFPL".to_string(), - creation_date: None, - ap_url: String::new(), // automatically updated when inserting - subtitle: "Testing".into(), - source: "Hello".into(), - cover_id: None, - }, - ) - .unwrap(); - PostAuthor::insert( - &conn, - NewPostAuthor { - post_id: post.id, - author_id: users[0].id, - }, - ) - .unwrap(); - let create = post.create_activity(&conn).unwrap(); - post.delete(&conn).unwrap(); - - match inbox(&conn, serde_json::to_value(create).unwrap()).unwrap() { - InboxResult::Post(p) => { - assert!(p.is_author(&conn, users[0].id).unwrap()); - assert_eq!(p.source, "Hello".to_owned()); - assert_eq!(p.blog_id, blogs[0].id); - assert_eq!(p.content, SafeString::new("Hello")); - assert_eq!(p.subtitle, "Testing".to_owned()); - assert_eq!(p.title, "Yo".to_owned()); - } - _ => panic!("Unexpected result"), - }; - Ok(()) - }); - } - // creates a post, get it's Create activity, delete the post, // "send" the Create to the inbox, and check it works #[test] @@ -1455,51 +1390,6 @@ mod tests { }); } - #[test] - fn create_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.create_activity(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "cc": [], - "id": "https://plu.me/~/BlogName/testing/activity", - "object": { - "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], - "cc": [], - "content": "Hello", - "id": "https://plu.me/~/BlogName/testing", - "license": "WTFPL", - "name": "Testing", - "published": format_datetime(&post.creation_date), - "source": { - "content": "Hello", - "mediaType": "text/markdown" - }, - "summary": "Bye", - "tag": [ - { - "href": "https://plu.me/@/user/", - "name": "@user", - "type": "Mention" - } - ], - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Article", - "url": "https://plu.me/~/BlogName/testing" - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Create" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn create_activity07() { let conn = db(); diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 69eb1dd0..32b3729e 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -724,7 +724,7 @@ impl User { Ok(posts .into_iter() .filter_map(|p| { - p.create_activity(conn) + p.create_activity07(conn) .ok() .and_then(|a| serde_json::to_value(a).ok()) }) diff --git a/src/routes/posts.rs b/src/routes/posts.rs index da48016f..626b8be4 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -15,7 +15,9 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast, ActivityStream, ApRequest}; +use plume_common::activity_pub::{ + broadcast, broadcast07, ActivityStream, ApRequest, LicensedArticle as LicensedArticle07, +}; use plume_common::utils::md_to_html; use plume_models::{ blogs::*, @@ -106,12 +108,12 @@ pub fn activity_details( slug: String, _ap: ApRequest, conn: DbConn, -) -> Result, Option> { +) -> Result, Option> { let blog = Blog::find_by_fqn(&conn, &blog).map_err(|_| None)?; let post = Post::find_by_slug(&conn, &slug, blog.id).map_err(|_| None)?; if post.published { Ok(ActivityStream::new( - post.to_activity(&conn) + post.to_activity07(&conn) .map_err(|_| String::from("Post serialization error"))?, )) } else { @@ -340,22 +342,22 @@ pub fn update( if post.published { if newly_published { let act = post - .create_activity(&conn) + .create_activity07(&conn) .expect("post::update: act error"); let dest = User::one_by_instance(&conn).expect("post::update: dest error"); rockets .worker - .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); Timeline::add_to_all_timelines(&conn, &post, Kind::Original).ok(); } else { let act = post - .update_activity(&conn) + .update_activity07(&conn) .expect("post::update: act error"); let dest = User::one_by_instance(&conn).expect("posts::update: dest error"); rockets .worker - .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); } } @@ -539,11 +541,11 @@ pub fn create( } let act = post - .create_activity(&conn) + .create_activity07(&conn) .expect("posts::create: activity error"); let dest = User::one_by_instance(&conn).expect("posts::create: dest error"); let worker = &rockets.worker; - worker.execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); + worker.execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); Timeline::add_to_all_timelines(&conn, &post, Kind::Original)?; } From 6cd68ab8b062d8591af6b18b0f041253029c10f7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:23:12 +0900 Subject: [PATCH 150/233] Use Post::update_activity07() instead of update_activity() --- plume-models/src/posts.rs | 86 +-------------------------------------- src/api/posts.rs | 6 +-- 2 files changed, 4 insertions(+), 88 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 3ffec9b1..57f40df5 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -4,7 +4,7 @@ use crate::{ Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN, }; use activitypub::{ - activity::{Delete, Update}, + activity::Delete, object::{Article, Image, Tombstone}, CustomObject, }; @@ -510,24 +510,6 @@ impl Post { Ok(act) } - pub fn update_activity(&self, conn: &Connection) -> Result { - let article = self.to_activity(conn)?; - let mut act = Update::default(); - act.object_props.set_id_string(format!( - "{}/update-{}", - self.ap_url, - Utc::now().timestamp() - ))?; - act.object_props - .set_to_link_vec::(article.object.object_props.to_link_vec()?)?; - act.object_props - .set_cc_link_vec::(article.object.object_props.cc_link_vec()?)?; - act.update_props - .set_actor_link(Id::new(self.get_authors(conn)?[0].clone().ap_url))?; - act.update_props.set_object_object(article)?; - Ok(act) - } - pub fn update_activity07(&self, conn: &Connection) -> Result { let article = self.to_activity07(conn)?; let to = article.to().ok_or(Error::MissingApProperty)?.clone(); @@ -1435,72 +1417,6 @@ mod tests { }); } - #[test] - fn update_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.update_activity(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "cc": [], - "id": "https://plu.me/~/BlogName/testing/update-", - "object": { - "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], - "cc": [], - "content": "Hello", - "id": "https://plu.me/~/BlogName/testing", - "license": "WTFPL", - "name": "Testing", - "published": format_datetime(&post.creation_date), - "source": { - "content": "Hello", - "mediaType": "text/markdown" - }, - "summary": "Bye", - "tag": [ - { - "href": "https://plu.me/@/user/", - "name": "@user", - "type": "Mention" - } - ], - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Article", - "url": "https://plu.me/~/BlogName/testing" - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Update" - }); - let actual = to_value(act)?; - - let id = actual["id"].to_string(); - let (id_pre, id_post) = id.rsplit_once("-").unwrap(); - assert_eq!(post.ap_url, "https://plu.me/~/BlogName/testing"); - assert_eq!( - id_pre, - to_value("\"https://plu.me/~/BlogName/testing/update") - .unwrap() - .as_str() - .unwrap() - ); - assert_eq!(id_post.len(), 11); - assert_eq!( - id_post.matches(char::is_numeric).collect::().len(), - 10 - ); - for (key, value) in actual.as_object().unwrap().into_iter() { - if key == "id" { - continue; - } - assert_json_eq!(value, expected.get(key).unwrap()); - } - - Ok(()) - }); - } - #[test] fn update_activity07() { let conn = db(); diff --git a/src/api/posts.rs b/src/api/posts.rs index 56c80da9..a1dcb639 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -3,7 +3,7 @@ use rocket_contrib::json::Json; use crate::api::{authorization::*, Api, ApiError}; use plume_api::posts::*; -use plume_common::{activity_pub::broadcast, utils::md_to_html}; +use plume_common::{activity_pub::broadcast07, utils::md_to_html}; use plume_models::{ blogs::Blog, db_conn::DbConn, instance::Instance, medias::Media, mentions::*, post_authors::*, posts::*, safe_string::SafeString, tags::*, timeline::*, users::User, Error, PlumeRocket, @@ -200,9 +200,9 @@ pub fn create( )?; } - let act = post.create_activity(&conn)?; + let act = post.create_activity07(&conn)?; let dest = User::one_by_instance(&conn)?; - worker.execute(move || broadcast(&author, act, dest, CONFIG.proxy().cloned())); + worker.execute(move || broadcast07(&author, act, dest, CONFIG.proxy().cloned())); } Timeline::add_to_all_timelines(&conn, &post, Kind::Original)?; From a8be31b177d713fd00d4efb0c5788701e8919de5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:26:59 +0900 Subject: [PATCH 151/233] Use Post::update_tags07() instead of update_tags() --- plume-models/src/posts.rs | 36 -------------------------------- plume-models/src/timeline/mod.rs | 5 ++++- src/routes/posts.rs | 4 ++-- 3 files changed, 6 insertions(+), 39 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 57f40df5..f7d057ec 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -568,42 +568,6 @@ impl Post { Ok(()) } - pub fn update_tags(&self, conn: &Connection, tags: Vec) -> Result<()> { - let tags_name = tags - .iter() - .filter_map(|t| t.name_string().ok()) - .collect::>(); - - let old_tags = Tag::for_post(&*conn, self.id)?; - let old_tags_name = old_tags - .iter() - .filter_map(|tag| { - if !tag.is_hashtag { - Some(tag.tag.clone()) - } else { - None - } - }) - .collect::>(); - - for t in tags { - if !t - .name_string() - .map(|n| old_tags_name.contains(&n)) - .unwrap_or(true) - { - Tag::from_activity(conn, &t, self.id, false)?; - } - } - - for ot in old_tags.iter().filter(|t| !t.is_hashtag) { - if !tags_name.contains(&ot.tag) { - ot.delete(conn)?; - } - } - Ok(()) - } - pub fn update_tags07(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() diff --git a/plume-models/src/timeline/mod.rs b/plume-models/src/timeline/mod.rs index d6b2a59d..db7e3602 100644 --- a/plume-models/src/timeline/mod.rs +++ b/plume-models/src/timeline/mod.rs @@ -623,7 +623,10 @@ mod tests { ) .unwrap(); gnu_post - .update_tags(&conn, vec![Tag::build_activity("free".to_owned()).unwrap()]) + .update_tags07( + &conn, + vec![Tag::build_activity07("free".to_owned()).unwrap()], + ) .unwrap(); PostAuthor::insert( &conn, diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 626b8be4..1f65cbb6 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -325,9 +325,9 @@ pub fn update( .filter(|t| !t.is_empty()) .collect::>() .into_iter() - .filter_map(|t| Tag::build_activity(t.to_string()).ok()) + .filter_map(|t| Tag::build_activity07(t.to_string()).ok()) .collect::>(); - post.update_tags(&conn, tags) + post.update_tags07(&conn, tags) .expect("post::update: tags error"); let hashtags = hashtags From a958300a58fdbdd19365ae1e1ba05dda4389d83b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:28:36 +0900 Subject: [PATCH 152/233] Use Post::update_hashtags07() instead of update_hashtags() --- plume-models/src/posts.rs | 38 +------------------------------------- src/routes/posts.rs | 4 ++-- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index f7d057ec..a4390dcb 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -27,7 +27,7 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, + Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -605,42 +605,6 @@ impl Post { Ok(()) } - pub fn update_hashtags(&self, conn: &Connection, tags: Vec) -> Result<()> { - let tags_name = tags - .iter() - .filter_map(|t| t.name_string().ok()) - .collect::>(); - - let old_tags = Tag::for_post(&*conn, self.id)?; - let old_tags_name = old_tags - .iter() - .filter_map(|tag| { - if tag.is_hashtag { - Some(tag.tag.clone()) - } else { - None - } - }) - .collect::>(); - - for t in tags { - if !t - .name_string() - .map(|n| old_tags_name.contains(&n)) - .unwrap_or(true) - { - Tag::from_activity(conn, &t, self.id, true)?; - } - } - - for ot in old_tags.into_iter().filter(|t| t.is_hashtag) { - if !tags_name.contains(&ot.tag) { - ot.delete(conn)?; - } - } - Ok(()) - } - pub fn update_hashtags07(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 1f65cbb6..6c973d4a 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -334,9 +334,9 @@ pub fn update( .into_iter() .collect::>() .into_iter() - .filter_map(|t| Tag::build_activity(t).ok()) + .filter_map(|t| Tag::build_activity07(t).ok()) .collect::>(); - post.update_hashtags(&conn, hashtags) + post.update_hashtags07(&conn, hashtags) .expect("post::update: hashtags error"); if post.published { From 2a85f775e905d79ff1a00de125726538ea21b8a2 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:31:24 +0900 Subject: [PATCH 153/233] Use Post::build_delete07() instead of build_delete() --- plume-models/src/posts.rs | 45 +-------------------------------------- src/routes/posts.rs | 6 +++--- 2 files changed, 4 insertions(+), 47 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index a4390dcb..2ce03101 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -4,8 +4,7 @@ use crate::{ Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN, }; use activitypub::{ - activity::Delete, - object::{Article, Image, Tombstone}, + object::{Article, Image}, CustomObject, }; use activitystreams::{ @@ -653,22 +652,6 @@ impl Post { .and_then(|c| c.url().ok()) } - pub fn build_delete(&self, conn: &Connection) -> Result { - let mut act = Delete::default(); - act.delete_props - .set_actor_link(self.get_authors(conn)?[0].clone().into_id())?; - - let mut tombstone = Tombstone::default(); - tombstone.object_props.set_id_string(self.ap_url.clone())?; - act.delete_props.set_object_object(tombstone)?; - - act.object_props - .set_id_string(format!("{}#delete", self.ap_url))?; - act.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?; - Ok(act) - } - pub fn build_delete07(&self, conn: &Connection) -> Result { let mut tombstone = Tombstone07::new(); tombstone.set_id(self.ap_url.parse()?); @@ -1411,32 +1394,6 @@ mod tests { }); } - #[test] - fn build_delete() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.build_delete(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "id": "https://plu.me/~/BlogName/testing#delete", - "object": { - "id": "https://plu.me/~/BlogName/testing", - "type": "Tombstone" - }, - "to": [ - "https://www.w3.org/ns/activitystreams#Public" - ], - "type": "Delete" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_delete07() { let conn = db(); diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 6c973d4a..ef76f1cf 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -16,7 +16,7 @@ use crate::routes::{ use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; use plume_common::activity_pub::{ - broadcast, broadcast07, ActivityStream, ApRequest, LicensedArticle as LicensedArticle07, + broadcast07, ActivityStream, ApRequest, LicensedArticle as LicensedArticle07, }; use plume_common::utils::md_to_html; use plume_models::{ @@ -606,7 +606,7 @@ pub fn delete( } let dest = User::one_by_instance(&conn)?; - let delete_activity = post.build_delete(&conn)?; + let delete_activity = post.build_delete07(&conn)?; inbox( &conn, serde_json::to_value(&delete_activity).map_err(Error::from)?, @@ -615,7 +615,7 @@ pub fn delete( let user_c = user.clone(); rockets .worker - .execute(move || broadcast(&user_c, delete_activity, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user_c, delete_activity, dest, CONFIG.proxy().cloned())); rockets .worker .execute_after(Duration::from_secs(10 * 60), move || { From 5b3a472b669c4a8d6e494a0fd0a27f8cdbb8a069 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:33:22 +0900 Subject: [PATCH 154/233] Use Post::to_activity07() instead of to_activity() --- plume-models/src/posts.rs | 115 +------------------------------------- 1 file changed, 2 insertions(+), 113 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 2ce03101..2977a661 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -3,10 +3,7 @@ use crate::{ post_authors::*, safe_string::SafeString, schema::posts, tags::*, timeline::*, users::User, Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN, }; -use activitypub::{ - object::{Article, Image}, - CustomObject, -}; +use activitypub::{object::Article, CustomObject}; use activitystreams::{ activity::{Create as Create07, Delete as Delete07, Update as Update07}, base::{AnyBase, Base}, @@ -19,7 +16,7 @@ use activitystreams::{ prelude::*, time::OffsetDateTime, }; -use chrono::{NaiveDateTime, TimeZone, Utc}; +use chrono::{NaiveDateTime, Utc}; use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; use once_cell::sync::Lazy; use plume_common::{ @@ -351,76 +348,6 @@ impl Post { })) } - pub fn to_activity(&self, conn: &Connection) -> Result { - let cc = self.get_receivers_urls(conn)?; - let to = vec![PUBLIC_VISIBILITY.to_string()]; - - let mut mentions_json = Mention::list_for_post(conn, self.id)? - .into_iter() - .map(|m| json!(m.to_activity(conn).ok())) - .collect::>(); - let mut tags_json = Tag::for_post(conn, self.id)? - .into_iter() - .map(|t| json!(t.to_activity().ok())) - .collect::>(); - mentions_json.append(&mut tags_json); - - let mut article = Article::default(); - article.object_props.set_name_string(self.title.clone())?; - article.object_props.set_id_string(self.ap_url.clone())?; - - let mut authors = self - .get_authors(conn)? - .into_iter() - .map(|x| Id::new(x.ap_url)) - .collect::>(); - authors.push(self.get_blog(conn)?.into_id()); // add the blog URL here too - article - .object_props - .set_attributed_to_link_vec::(authors)?; - article - .object_props - .set_content_string(self.content.get().clone())?; - article.ap_object_props.set_source_object(Source { - content: self.source.clone(), - media_type: String::from("text/markdown"), - })?; - article - .object_props - .set_published_utctime(Utc.from_utc_datetime(&self.creation_date))?; - article - .object_props - .set_summary_string(self.subtitle.clone())?; - article.object_props.tag = Some(json!(mentions_json)); - - if let Some(media_id) = self.cover_id { - let media = Media::get(conn, media_id)?; - let mut cover = Image::default(); - cover.object_props.set_url_string(media.url()?)?; - if media.sensitive { - cover - .object_props - .set_summary_string(media.content_warning.unwrap_or_default())?; - } - cover.object_props.set_content_string(media.alt_text)?; - cover - .object_props - .set_attributed_to_link_vec(vec![User::get(conn, media.owner_id)?.into_id()])?; - article.object_props.set_icon_object(cover)?; - } - - article.object_props.set_url_string(self.ap_url.clone())?; - article - .object_props - .set_to_link_vec::(to.into_iter().map(Id::new).collect())?; - article - .object_props - .set_cc_link_vec::(cc.into_iter().map(Id::new).collect())?; - let mut license = Licensed::default(); - license.set_license_string(self.license.clone())?; - Ok(LicensedArticle::new(article, license)) - } - pub fn to_activity07(&self, conn: &Connection) -> Result { let cc = self.get_receivers_urls(conn)?; let to = vec![PUBLIC_VISIBILITY.to_string()]; @@ -1207,44 +1134,6 @@ mod tests { ); } - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.to_activity(&conn)?; - - let expected = json!({ - "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], - "cc": [], - "content": "Hello", - "id": "https://plu.me/~/BlogName/testing", - "license": "WTFPL", - "name": "Testing", - "published": format_datetime(&post.creation_date), - "source": { - "content": "Hello", - "mediaType": "text/markdown" - }, - "summary": "Bye", - "tag": [ - { - "href": "https://plu.me/@/user/", - "name": "@user", - "type": "Mention" - } - ], - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Article", - "url": "https://plu.me/~/BlogName/testing" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = db(); From 68a01d5f9be6b3850e3f26aec9b5fea9fe00a7ed Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:47:17 +0900 Subject: [PATCH 155/233] Add activitystreams to Plume's dependencies --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 3195f505..faf43af4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ webfinger = "0.4.1" tracing = "0.1.34" tracing-subscriber = "0.3.10" riker = "0.4.2" +activitystreams = "0.7.0-alpha.18" [[bin]] name = "plume" From 803680186bc8c9db7b5bd5700c98eb16e94959d9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:48:02 +0900 Subject: [PATCH 156/233] Add Blog::outbox07() --- plume-models/src/blogs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 17f0eadb..091dd03a 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -311,6 +311,10 @@ impl Blog { )))?; Ok(coll) } + + pub fn outbox07(&self, conn: &Connection) -> Result> { + self.outbox_collection07(conn).map(ActivityStream::new) + } pub fn outbox_collection07(&self, conn: &Connection) -> Result { let acts = self.get_activities(conn); let acts = acts From f608f7a4d643238d9a2de78e2e12b58532005f81 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:48:17 +0900 Subject: [PATCH 157/233] Install activitystreams --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 8e0d5d79..291f450f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3157,6 +3157,7 @@ name = "plume" version = "0.7.1" dependencies = [ "activitypub", + "activitystreams", "atom_syndication", "chrono", "clap", From cd6c57b9c5041dae1b13eaf30efb86dbe5da1376 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:53:35 +0900 Subject: [PATCH 158/233] Use Blog::outbox07() instead of outbox() --- plume-models/src/blogs.rs | 48 +-------------------------------------- src/routes/blogs.rs | 7 +++--- 2 files changed, 5 insertions(+), 50 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 091dd03a..ba8fef89 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -2,12 +2,7 @@ use crate::{ db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, }; -use activitypub::{ - actor::Group, - collection::{OrderedCollection, OrderedCollectionPage}, - object::Image, - CustomObject, -}; +use activitypub::{actor::Group, collection::OrderedCollectionPage, object::Image, CustomObject}; use activitystreams::{ actor::{ApActor, ApActorExt, AsApActor, Group as Group07}, base::AnyBase, @@ -293,25 +288,6 @@ impl Blog { Ok(CustomGroup07::new(blog, ap_signature, source)) } - pub fn outbox(&self, conn: &Connection) -> Result> { - self.outbox_collection(conn).map(ActivityStream::new) - } - pub fn outbox_collection(&self, conn: &Connection) -> Result { - let mut coll = OrderedCollection::default(); - coll.collection_props.items = serde_json::to_value(self.get_activities(conn))?; - coll.collection_props - .set_total_items_u64(self.get_activities(conn).len() as u64)?; - coll.collection_props - .set_first_link(Id::new(&format!("{}?page=1", &self.outbox_url)))?; - coll.collection_props.set_last_link(Id::new(&format!( - "{}?page={}", - &self.outbox_url, - (self.get_activities(conn).len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64 - / ITEMS_PER_PAGE as u64 - )))?; - Ok(coll) - } - pub fn outbox07(&self, conn: &Connection) -> Result> { self.outbox_collection07(conn).map(ActivityStream::new) } @@ -1177,28 +1153,6 @@ pub(crate) mod tests { }); } - #[test] - fn outbox_collection() { - let conn = &db(); - conn.test_transaction::<_, Error, _>(|| { - let (_users, blogs) = fill_database(conn); - let blog = &blogs[0]; - let act = blog.outbox_collection(conn)?; - - let expected = json!({ - "items": [], - "totalItems": 0, - "first": "https://plu.me/~/BlogName/outbox?page=1", - "last": "https://plu.me/~/BlogName/outbox?page=0", - "type": "OrderedCollection" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn outbox_collection07() { let conn = &db(); diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index c56b5a6e..25c09c91 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -1,4 +1,5 @@ -use activitypub::collection::{OrderedCollection, OrderedCollectionPage}; +use activitypub::collection::OrderedCollectionPage; +use activitystreams::collection::OrderedCollection as OrderedCollection07; use diesel::SaveChangesDsl; use rocket::{ http::ContentType, @@ -347,9 +348,9 @@ pub fn update( } #[get("/~//outbox")] -pub fn outbox(name: String, conn: DbConn) -> Option> { +pub fn outbox(name: String, conn: DbConn) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; - blog.outbox(&conn).ok() + blog.outbox07(&conn).ok() } #[allow(unused_variables)] #[get("/~//outbox?")] From 0524b0b153fe2ab8883afc282192315549175bf5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 22:56:54 +0900 Subject: [PATCH 159/233] Add Blog::outbox_page07() --- plume-models/src/blogs.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index ba8fef89..bb5666e8 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -342,6 +342,14 @@ impl Blog { coll.collection_props.items = serde_json::to_value(acts)?; Ok(coll) } + pub fn outbox_page07( + &self, + conn: &Connection, + (min, max): (i32, i32), + ) -> Result> { + self.outbox_collection_page07(conn, (min, max)) + .map(ActivityStream::new) + } pub fn outbox_collection_page07( &self, conn: &Connection, From 4b4c22cf8a9948fa70130d2f44fd574730a4c4f5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:01:26 +0900 Subject: [PATCH 160/233] Use Blog::outbox_page07() instead of outbox_page() --- plume-models/src/blogs.rs | 69 +++++---------------------------------- src/routes/blogs.rs | 7 ++-- 2 files changed, 11 insertions(+), 65 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index bb5666e8..7c7ee559 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -2,13 +2,11 @@ use crate::{ db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, }; -use activitypub::{actor::Group, collection::OrderedCollectionPage, object::Image, CustomObject}; +use activitypub::{actor::Group, object::Image, CustomObject}; use activitystreams::{ actor::{ApActor, ApActorExt, AsApActor, Group as Group07}, base::AnyBase, - collection::{ - OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, - }, + collection::{OrderedCollection, OrderedCollectionPage}, iri_string::types::IriString, object::{kind::ImageType, ApObject, Image as Image07, ObjectExt}, prelude::*, @@ -288,17 +286,17 @@ impl Blog { Ok(CustomGroup07::new(blog, ap_signature, source)) } - pub fn outbox07(&self, conn: &Connection) -> Result> { + pub fn outbox07(&self, conn: &Connection) -> Result> { self.outbox_collection07(conn).map(ActivityStream::new) } - pub fn outbox_collection07(&self, conn: &Connection) -> Result { + pub fn outbox_collection07(&self, conn: &Connection) -> Result { let acts = self.get_activities(conn); let acts = acts .iter() .filter_map(|value| AnyBase::from_arbitrary_json(value).ok()) .collect::>(); let n_acts = acts.len(); - let mut coll = OrderedCollection07::new(); + let mut coll = OrderedCollection::new(); coll.set_many_items(acts); coll.set_total_items(n_acts as u64); coll.set_first(format!("{}?page=1", &self.outbox_url).parse::()?); @@ -312,41 +310,11 @@ impl Blog { ); Ok(coll) } - pub fn outbox_page( - &self, - conn: &Connection, - (min, max): (i32, i32), - ) -> Result> { - self.outbox_collection_page(conn, (min, max)) - .map(ActivityStream::new) - } - pub fn outbox_collection_page( - &self, - conn: &Connection, - (min, max): (i32, i32), - ) -> Result { - let mut coll = OrderedCollectionPage::default(); - let acts = self.get_activity_page(conn, (min, max)); - //This still doesn't do anything because the outbox - //doesn't do anything yet - coll.collection_page_props.set_next_link(Id::new(&format!( - "{}?page={}", - &self.outbox_url, - min / ITEMS_PER_PAGE + 1 - )))?; - coll.collection_page_props.set_prev_link(Id::new(&format!( - "{}?page={}", - &self.outbox_url, - min / ITEMS_PER_PAGE - 1 - )))?; - coll.collection_props.items = serde_json::to_value(acts)?; - Ok(coll) - } pub fn outbox_page07( &self, conn: &Connection, (min, max): (i32, i32), - ) -> Result> { + ) -> Result> { self.outbox_collection_page07(conn, (min, max)) .map(ActivityStream::new) } @@ -354,8 +322,8 @@ impl Blog { &self, conn: &Connection, (min, max): (i32, i32), - ) -> Result { - let mut coll = OrderedCollectionPage07::new(); + ) -> Result { + let mut coll = OrderedCollectionPage::new(); let acts = self.get_activity_page(conn, (min, max)); //This still doesn't do anything because the outbox //doesn't do anything yet @@ -1183,27 +1151,6 @@ pub(crate) mod tests { }); } - #[test] - fn outbox_collection_page() { - let conn = &db(); - conn.test_transaction::<_, Error, _>(|| { - let (_users, blogs) = fill_database(conn); - let blog = &blogs[0]; - let act = blog.outbox_collection_page(conn, (33, 36))?; - - let expected = json!({ - "next": "https://plu.me/~/BlogName/outbox?page=3", - "prev": "https://plu.me/~/BlogName/outbox?page=1", - "items": [], - "type": "OrderedCollectionPage" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn outbox_collection_page07() { let conn = &db(); diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index 25c09c91..85071313 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -1,5 +1,4 @@ -use activitypub::collection::OrderedCollectionPage; -use activitystreams::collection::OrderedCollection as OrderedCollection07; +use activitystreams::collection::{OrderedCollection, OrderedCollectionPage}; use diesel::SaveChangesDsl; use rocket::{ http::ContentType, @@ -348,7 +347,7 @@ pub fn update( } #[get("/~//outbox")] -pub fn outbox(name: String, conn: DbConn) -> Option> { +pub fn outbox(name: String, conn: DbConn) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; blog.outbox07(&conn).ok() } @@ -360,7 +359,7 @@ pub fn outbox_page( conn: DbConn, ) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; - blog.outbox_page(&conn, page.limits()).ok() + blog.outbox_page07(&conn, page.limits()).ok() } #[get("/~//atom.xml")] pub fn atom_feed(name: String, conn: DbConn) -> Option> { From 811c20c8fb05fe2d3bdb8e9c5346fe92dab5cbdf Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:07:05 +0900 Subject: [PATCH 161/233] Use Blog::to_activity07() instead of to_activity() --- plume-models/src/blogs.rs | 112 +------------------------------------- src/routes/blogs.rs | 4 +- 2 files changed, 4 insertions(+), 112 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 7c7ee559..e9f9fd1a 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -2,7 +2,7 @@ use crate::{ db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, }; -use activitypub::{actor::Group, object::Image, CustomObject}; +use activitypub::{actor::Group, CustomObject}; use activitystreams::{ actor::{ApActor, ApActorExt, AsApActor, Group as Group07}, base::AnyBase, @@ -22,7 +22,7 @@ use openssl::{ use plume_common::activity_pub::{ inbox::{AsActor, FromId}, sign, ActivityStream, ApSignature, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, - PublicKey, PublicKey07, Source, SourceProperty, ToAsString, ToAsUri, + PublicKey07, Source, SourceProperty, ToAsString, ToAsUri, }; use webfinger::*; @@ -163,68 +163,6 @@ impl Blog { }) } - pub fn to_activity(&self, conn: &Connection) -> Result { - let mut blog = Group::default(); - blog.ap_actor_props - .set_preferred_username_string(self.actor_id.clone())?; - blog.object_props.set_name_string(self.title.clone())?; - blog.ap_actor_props - .set_outbox_string(self.outbox_url.clone())?; - blog.ap_actor_props - .set_inbox_string(self.inbox_url.clone())?; - blog.object_props - .set_summary_string(self.summary_html.to_string())?; - blog.ap_object_props.set_source_object(Source { - content: self.summary.clone(), - media_type: String::from("text/markdown"), - })?; - - let mut icon = Image::default(); - icon.object_props.set_url_string( - self.icon_id - .and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok()) - .unwrap_or_default(), - )?; - icon.object_props.set_attributed_to_link( - self.icon_id - .and_then(|id| { - Media::get(conn, id) - .and_then(|m| Ok(User::get(conn, m.owner_id)?.into_id())) - .ok() - }) - .unwrap_or_else(|| Id::new(String::new())), - )?; - blog.object_props.set_icon_object(icon)?; - - let mut banner = Image::default(); - banner.object_props.set_url_string( - self.banner_id - .and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok()) - .unwrap_or_default(), - )?; - banner.object_props.set_attributed_to_link( - self.banner_id - .and_then(|id| { - Media::get(conn, id) - .and_then(|m| Ok(User::get(conn, m.owner_id)?.into_id())) - .ok() - }) - .unwrap_or_else(|| Id::new(String::new())), - )?; - blog.object_props.set_image_object(banner)?; - - blog.object_props.set_id_string(self.ap_url.clone())?; - - let mut public_key = PublicKey::default(); - public_key.set_id_string(format!("{}#main-key", self.ap_url))?; - public_key.set_owner_string(self.ap_url.clone())?; - public_key.set_public_key_pem_string(self.public_key.clone())?; - let mut ap_signature = ApSignature::default(); - ap_signature.set_public_key_publickey(public_key)?; - - Ok(CustomGroup::new(blog, ap_signature)) - } - pub fn to_activity07(&self, conn: &Connection) -> Result { let mut blog = ApActor::new(self.inbox_url.parse()?, Group07::new()); blog.set_preferred_username(self.actor_id.clone()); @@ -1040,52 +978,6 @@ pub(crate) mod tests { }) } - #[test] - fn to_activity() { - let conn = &db(); - conn.test_transaction::<_, Error, _>(|| { - let (_users, blogs) = fill_database(&conn); - let blog = &blogs[0]; - let act = blog.to_activity(conn)?; - - let expected = json!({ - "followers": null, - "following": null, - "icon": { - "attributedTo": "https://plu.me/@/admin/", - "type": "Image", - "url": "https://plu.me/aaa.png" - }, - "id": "https://plu.me/~/BlogName/", - "image": { - "attributedTo": "https://plu.me/@/admin/", - "type": "Image", - "url": "https://plu.me/bbb.png" - }, - "inbox": "https://plu.me/~/BlogName/inbox", - "liked": null, - "name": "Blog name", - "outbox": "https://plu.me/~/BlogName/outbox", - "preferredUsername": "BlogName", - "publicKey": { - "id": "https://plu.me/~/BlogName/#main-key", - "owner": "https://plu.me/~/BlogName/", - "publicKeyPem": blog.public_key - }, - "source": { - "content": "This is a small blog", - "mediaType": "text/markdown" - }, - "summary": "", - "type": "Group" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = &db(); diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index 85071313..1135d9ed 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -12,7 +12,7 @@ use validator::{Validate, ValidationError, ValidationErrors}; use crate::routes::{errors::ErrorPage, Page, RespondOrRedirect}; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{ActivityStream, ApRequest}; +use plume_common::activity_pub::{ActivityStream, ApRequest, CustomGroup}; use plume_common::utils; use plume_models::{ blog_authors::*, blogs::*, db_conn::DbConn, instance::Instance, medias::*, posts::Post, @@ -49,7 +49,7 @@ pub fn activity_details( _ap: ApRequest, ) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; - Some(ActivityStream::new(blog.to_activity(&conn).ok()?)) + Some(ActivityStream::new(blog.to_activity07(&conn).ok()?)) } #[get("/blogs/new")] From bc96af7f5f108847500afa9427228c8c99b149a1 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:08:41 +0900 Subject: [PATCH 162/233] Remove unused blogs::CustomGroup --- plume-models/src/blogs.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index e9f9fd1a..8ba29a3b 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -2,7 +2,6 @@ use crate::{ db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, }; -use activitypub::{actor::Group, CustomObject}; use activitystreams::{ actor::{ApActor, ApActorExt, AsApActor, Group as Group07}, base::AnyBase, @@ -21,13 +20,11 @@ use openssl::{ }; use plume_common::activity_pub::{ inbox::{AsActor, FromId}, - sign, ActivityStream, ApSignature, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, - PublicKey07, Source, SourceProperty, ToAsString, ToAsUri, + sign, ActivityStream, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, PublicKey07, + Source, SourceProperty, ToAsString, ToAsUri, }; use webfinger::*; -pub type CustomGroup = CustomObject; - #[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)] #[changeset_options(treat_none_as_null = "true")] pub struct Blog { From 40ce515e6c736474b2486376d3058ed0a710bc3c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:09:37 +0900 Subject: [PATCH 163/233] Don't rename activitystreams' tokens to 07 --- plume-models/src/blogs.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 8ba29a3b..96aec540 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -3,11 +3,11 @@ use crate::{ schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, }; use activitystreams::{ - actor::{ApActor, ApActorExt, AsApActor, Group as Group07}, + actor::{ApActor, ApActorExt, AsApActor, Group}, base::AnyBase, collection::{OrderedCollection, OrderedCollectionPage}, iri_string::types::IriString, - object::{kind::ImageType, ApObject, Image as Image07, ObjectExt}, + object::{kind::ImageType, ApObject, Image, ObjectExt}, prelude::*, }; use chrono::NaiveDateTime; @@ -20,8 +20,8 @@ use openssl::{ }; use plume_common::activity_pub::{ inbox::{AsActor, FromId}, - sign, ActivityStream, ApSignature07, CustomGroup as CustomGroup07, Id, IntoId, PublicKey07, - Source, SourceProperty, ToAsString, ToAsUri, + sign, ActivityStream, ApSignature07, CustomGroup, Id, IntoId, PublicKey07, Source, + SourceProperty, ToAsString, ToAsUri, }; use webfinger::*; @@ -160,8 +160,8 @@ impl Blog { }) } - pub fn to_activity07(&self, conn: &Connection) -> Result { - let mut blog = ApActor::new(self.inbox_url.parse()?, Group07::new()); + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut blog = ApActor::new(self.inbox_url.parse()?, Group::new()); blog.set_preferred_username(self.actor_id.clone()); blog.set_name(self.title.clone()); blog.set_outbox(self.outbox_url.parse()?); @@ -173,7 +173,7 @@ impl Blog { }, }; - let mut icon = Image07::new(); + let mut icon = Image::new(); let _ = self.icon_id.map(|id| { Media::get(conn, id).and_then(|m| { let _ = m @@ -190,7 +190,7 @@ impl Blog { }); blog.set_icon(icon.into_any_base()?); - let mut banner = Image07::new(); + let mut banner = Image::new(); let _ = self.banner_id.map(|id| { Media::get(conn, id).and_then(|m| { let _ = m @@ -218,7 +218,7 @@ impl Blog { public_key: pub_key, }; - Ok(CustomGroup07::new(blog, ap_signature, source)) + Ok(CustomGroup::new(blog, ap_signature, source)) } pub fn outbox07(&self, conn: &Connection) -> Result> { @@ -363,13 +363,13 @@ impl IntoId for Blog { impl FromId for Blog { type Error = Error; - type Object = CustomGroup07; + type Object = CustomGroup; fn from_db07(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, acct: CustomGroup07) -> Result { + fn from_activity07(conn: &DbConn, acct: CustomGroup) -> Result { let (name, outbox_url, inbox_url) = { let actor = acct.ap_actor_ref(); let name = actor @@ -412,7 +412,7 @@ impl FromId for Blog { .icon() .and_then(|icons| { icons.iter().next().and_then(|icon| { - let icon = icon.to_owned().extend::().ok()??; + let icon = icon.to_owned().extend::().ok()??; let owner = icon.attributed_to()?.to_as_uri()?; Media::save_remote( conn, @@ -429,7 +429,7 @@ impl FromId for Blog { .image() .and_then(|banners| { banners.iter().next().and_then(|banner| { - let banner = banner.to_owned().extend::().ok()??; + let banner = banner.to_owned().extend::().ok()??; let owner = banner.attributed_to()?.to_as_uri()?; Media::save_remote( conn, From ae9c9262f7d9b89bfca0aa61b8b7e433e9ab798a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:16:55 +0900 Subject: [PATCH 164/233] Use Reshare::build_undo07() instead of build_undo() --- plume-models/src/reshares.rs | 56 ++++-------------------------------- src/routes/reshares.rs | 6 ++-- 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 05973f89..663fdc8d 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -2,9 +2,9 @@ use crate::{ db_conn::DbConn, instance::Instance, notifications::*, posts::Post, schema::reshares, timeline::*, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::activity::{Announce, Undo}; +use activitypub::activity::Announce; use activitystreams::{ - activity::{ActorAndObjectRef, Announce as Announce07, Undo as Undo07}, + activity::{ActorAndObjectRef, Announce as Announce07, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -113,23 +113,8 @@ impl Reshare { Ok(()) } - pub fn build_undo(&self, conn: &Connection) -> Result { - let mut act = Undo::default(); - act.undo_props - .set_actor_link(User::get(conn, self.user_id)?.into_id())?; - act.undo_props.set_object_object(self.to_activity(conn)?)?; - act.object_props - .set_id_string(format!("{}#delete", self.ap_url))?; - act.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - act.object_props - .set_cc_link_vec(vec![Id::new(self.get_user(conn)?.followers_endpoint)])?; - - Ok(act) - } - - pub fn build_undo07(&self, conn: &Connection) -> Result { - let mut act = Undo07::new( + pub fn build_undo07(&self, conn: &Connection) -> Result { + let mut act = Undo::new( User::get(conn, self.user_id)?.ap_url.parse::()?, AnyBase::from_extended(self.to_activity07(conn)?)?, ); @@ -214,7 +199,7 @@ impl FromId for Reshare { } } -impl AsObject for Reshare { +impl AsObject for Reshare { type Error = Error; type Output = (); @@ -301,37 +286,6 @@ mod test { }); } - #[test] - fn build_undo() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (posts, _users, _blogs) = fill_database(&conn); - let post = &posts[0]; - let user = &post.get_authors(&conn)?[0]; - let reshare = Reshare::insert(&*conn, NewReshare::new(post, user))?; - let act = reshare.build_undo(&*conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": "https://plu.me/@/admin/reshare/https://plu.me/~/BlogName/testing#delete", - "object": { - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": "https://plu.me/@/admin/reshare/https://plu.me/~/BlogName/testing", - "object": "https://plu.me/~/BlogName/testing", - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Announce" - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Undo", - }); - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_undo07() { let conn = db(); diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index b6d11c8a..8010b846 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -3,7 +3,7 @@ use rocket_i18n::I18n; use crate::routes::errors::ErrorPage; use crate::utils::requires_login; -use plume_common::activity_pub::broadcast; +use plume_common::activity_pub::{broadcast, broadcast07}; use plume_models::{ blogs::Blog, db_conn::DbConn, inbox::inbox, posts::Post, reshares::*, timeline::*, users::User, Error, PlumeRocket, CONFIG, @@ -33,7 +33,7 @@ pub fn create( .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } else { let reshare = Reshare::find_by_user_on_post(&conn, user.id, post.id)?; - let delete_act = reshare.build_undo(&conn)?; + let delete_act = reshare.build_undo07(&conn)?; inbox( &conn, serde_json::to_value(&delete_act).map_err(Error::from)?, @@ -42,7 +42,7 @@ pub fn create( let dest = User::one_by_instance(&conn)?; rockets .worker - .execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, delete_act, dest, CONFIG.proxy().cloned())); } Ok(Redirect::to(uri!( From f365041a45af9caad9318c9aeebbe09cfdc1544c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:18:47 +0900 Subject: [PATCH 165/233] Use Reshare::to_activity07() instead of to_activity() --- plume-models/src/reshares.rs | 54 +++++------------------------------- src/routes/reshares.rs | 6 ++-- 2 files changed, 10 insertions(+), 50 deletions(-) diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 663fdc8d..3c55658e 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -2,9 +2,8 @@ use crate::{ db_conn::DbConn, instance::Instance, notifications::*, posts::Post, schema::reshares, timeline::*, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::activity::Announce; use activitystreams::{ - activity::{ActorAndObjectRef, Announce as Announce07, Undo}, + activity::{ActorAndObjectRef, Announce, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -14,7 +13,7 @@ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Id, IntoId, PUBLIC_VISIBILITY, + PUBLIC_VISIBILITY, }; #[derive(Clone, Queryable, Identifiable)] @@ -66,23 +65,8 @@ impl Reshare { User::get(conn, self.user_id) } - pub fn to_activity(&self, conn: &Connection) -> Result { - let mut act = Announce::default(); - act.announce_props - .set_actor_link(User::get(conn, self.user_id)?.into_id())?; - act.announce_props - .set_object_link(Post::get(conn, self.post_id)?.into_id())?; - act.object_props.set_id_string(self.ap_url.clone())?; - act.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - act.object_props - .set_cc_link_vec(vec![Id::new(self.get_user(conn)?.followers_endpoint)])?; - - Ok(act) - } - - pub fn to_activity07(&self, conn: &Connection) -> Result { - let mut act = Announce07::new( + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut act = Announce::new( User::get(conn, self.user_id)?.ap_url.parse::()?, Post::get(conn, self.post_id)?.ap_url.parse::()?, ); @@ -129,7 +113,7 @@ impl Reshare { } } -impl AsObject for Post { +impl AsObject for Post { type Error = Error; type Output = Reshare; @@ -152,13 +136,13 @@ impl AsObject for Post { impl FromId for Reshare { type Error = Error; - type Object = Announce07; + type Object = Announce; fn from_db07(conn: &DbConn, id: &str) -> Result { Reshare::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, act: Announce07) -> Result { + fn from_activity07(conn: &DbConn, act: Announce) -> Result { let res = Reshare::insert( conn, NewReshare { @@ -238,30 +222,6 @@ mod test { use assert_json_diff::assert_json_eq; use serde_json::{json, to_value}; - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (posts, _users, _blogs) = fill_database(&conn); - let post = &posts[0]; - let user = &post.get_authors(&conn)?[0]; - let reshare = Reshare::insert(&*conn, NewReshare::new(post, user))?; - let act = reshare.to_activity(&conn).unwrap(); - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": "https://plu.me/@/admin/reshare/https://plu.me/~/BlogName/testing", - "object": "https://plu.me/~/BlogName/testing", - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Announce", - }); - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = db(); diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index 8010b846..2c14cf9f 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -3,7 +3,7 @@ use rocket_i18n::I18n; use crate::routes::errors::ErrorPage; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast, broadcast07}; +use plume_common::activity_pub::broadcast07; use plume_models::{ blogs::Blog, db_conn::DbConn, inbox::inbox, posts::Post, reshares::*, timeline::*, users::User, Error, PlumeRocket, CONFIG, @@ -27,10 +27,10 @@ pub fn create( Timeline::add_to_all_timelines(&conn, &post, Kind::Reshare(&user))?; let dest = User::one_by_instance(&conn)?; - let act = reshare.to_activity(&conn)?; + let act = reshare.to_activity07(&conn)?; rockets .worker - .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); } else { let reshare = Reshare::find_by_user_on_post(&conn, user.id, post.id)?; let delete_act = reshare.build_undo07(&conn)?; From 6cc43c242074b1e717de4657da34397039b496d4 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:23:28 +0900 Subject: [PATCH 166/233] Use Comment::create_activity07() instead of create_activity() --- plume-models/src/comments.rs | 112 +---------------------------------- src/routes/comments.rs | 6 +- 2 files changed, 4 insertions(+), 114 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index d4a9bd61..34ae1e91 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -12,7 +12,7 @@ use crate::{ Connection, Error, Result, CONFIG, }; use activitypub::{ - activity::{Create, Delete}, + activity::Delete, link, object::{Note, Tombstone}, }; @@ -189,24 +189,6 @@ impl Comment { Ok(note) } - pub fn create_activity(&self, conn: &DbConn) -> Result { - let author = User::get(conn, self.author_id)?; - - let note = self.to_activity(conn)?; - let mut act = Create::default(); - act.create_props.set_actor_link(author.into_id())?; - act.create_props.set_object_object(note.clone())?; - act.object_props.set_id_string(format!( - "{}/activity", - self.ap_url.clone().ok_or(Error::MissingApProperty)?, - ))?; - act.object_props - .set_to_link_vec(note.object_props.to_link_vec::()?)?; - act.object_props - .set_cc_link_vec(vec![Id::new(self.get_author(conn)?.followers_endpoint)])?; - Ok(act) - } - pub fn create_activity07(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; @@ -528,98 +510,6 @@ mod tests { (comment, posts, users, blogs) } - // creates a post, get it's Create activity, delete the post, - // "send" the Create to the inbox, and check it works - #[test] - fn self_federation() { - let conn = &db(); - conn.test_transaction::<_, (), _>(|| { - let (original_comm, posts, users, _blogs) = prepare_activity(&conn); - let act = original_comm.create_activity(&conn).unwrap(); - - assert_json_eq!(to_value(&act).unwrap(), json!({ - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": format!("https://plu.me/~/BlogName/testing/comment/{}/activity", original_comm.id), - "object": { - "attributedTo": "https://plu.me/@/admin/", - "content": r###"

My comment, mentioning to @user

-"###, - "id": format!("https://plu.me/~/BlogName/testing/comment/{}", original_comm.id), - "inReplyTo": "https://plu.me/~/BlogName/testing", - "published": format_datetime(&original_comm.creation_date), - "summary": "My CW", - "tag": [ - { - "href": "https://plu.me/@/user/", - "name": "@user", - "type": "Mention" - } - ], - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Note" - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Create", - })); - - let reply = Comment::insert( - conn, - NewComment { - content: SafeString::new(""), - in_response_to_id: Some(original_comm.id), - post_id: posts[0].id, - author_id: users[1].id, - ap_url: None, - sensitive: false, - spoiler_text: "".into(), - public_visibility: true, - }, - ) - .unwrap(); - let reply_act = reply.create_activity(&conn).unwrap(); - - assert_json_eq!(to_value(&reply_act).unwrap(), json!({ - "actor": "https://plu.me/@/user/", - "cc": ["https://plu.me/@/user/followers"], - "id": format!("https://plu.me/~/BlogName/testing/comment/{}/activity", reply.id), - "object": { - "attributedTo": "https://plu.me/@/user/", - "content": "", - "id": format!("https://plu.me/~/BlogName/testing/comment/{}", reply.id), - "inReplyTo": format!("https://plu.me/~/BlogName/testing/comment/{}", original_comm.id), - "published": format_datetime(&reply.creation_date), - "summary": "", - "tag": [], - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Note" - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Create" - })); - - inbox( - &conn, - serde_json::to_value(original_comm.build_delete(&conn).unwrap()).unwrap(), - ) - .unwrap(); - - match inbox(&conn, to_value(act).unwrap()).unwrap() { - InboxResult::Commented(c) => { - // TODO: one is HTML, the other markdown: assert_eq!(c.content, original_comm.content); - assert_eq!(c.in_response_to_id, original_comm.in_response_to_id); - assert_eq!(c.post_id, original_comm.post_id); - assert_eq!(c.author_id, original_comm.author_id); - assert_eq!(c.ap_url, original_comm.ap_url); - assert_eq!(c.spoiler_text, original_comm.spoiler_text); - assert_eq!(c.public_visibility, original_comm.public_visibility); - } - _ => panic!("Unexpected result"), - }; - Ok(()) - }) - } - // creates a post, get it's Create activity, delete the post, // "send" the Create to the inbox, and check it works #[test] diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 5585afff..9739f2e4 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -11,7 +11,7 @@ use std::time::Duration; use crate::routes::errors::ErrorPage; use crate::template_utils::IntoContext; use plume_common::{ - activity_pub::{broadcast, ActivityStream, ApRequest}, + activity_pub::{broadcast, broadcast07, ActivityStream, ApRequest}, utils, }; use plume_models::{ @@ -66,7 +66,7 @@ pub fn create( ) .expect("comments::create: insert error"); let new_comment = comm - .create_activity(&conn) + .create_activity07(&conn) .expect("comments::create: activity error"); // save mentions @@ -88,7 +88,7 @@ pub fn create( let dest = User::one_by_instance(&conn).expect("comments::create: dest error"); let user_clone = user.clone(); rockets.worker.execute(move || { - broadcast(&user_clone, new_comment, dest, CONFIG.proxy().cloned()) + broadcast07(&user_clone, new_comment, dest, CONFIG.proxy().cloned()) }); Flash::success( From b5e1076b0e7c9a1fb2482c5ea3177dfc33f1a42a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:26:25 +0900 Subject: [PATCH 167/233] Use Comment::build_delete07() instead of build_delete() --- plume-models/src/comments.rs | 61 +++++------------------------------- src/routes/comments.rs | 6 ++-- 2 files changed, 10 insertions(+), 57 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 34ae1e91..33da7d97 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -11,17 +11,13 @@ use crate::{ users::User, Connection, Error, Result, CONFIG, }; -use activitypub::{ - activity::Delete, - link, - object::{Note, Tombstone}, -}; +use activitypub::{link, object::Note}; use activitystreams::{ - activity::{Create as Create07, Delete as Delete07}, + activity::{Create as Create07, Delete}, base::{AnyBase, Base}, iri_string::types::IriString, link::{self as link07, kind::MentionType}, - object::{Note as Note07, Tombstone as Tombstone07}, + object::{Note as Note07, Tombstone}, prelude::*, primitives::OneOrMany, time::OffsetDateTime, @@ -236,27 +232,8 @@ impl Comment { Ok(()) } - pub fn build_delete(&self, conn: &Connection) -> Result { - let mut act = Delete::default(); - act.delete_props - .set_actor_link(self.get_author(conn)?.into_id())?; - - let mut tombstone = Tombstone::default(); - tombstone - .object_props - .set_id_string(self.ap_url.clone().ok_or(Error::MissingApProperty)?)?; - act.delete_props.set_object_object(tombstone)?; - - act.object_props - .set_id_string(format!("{}#delete", self.ap_url.clone().unwrap()))?; - act.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?; - - Ok(act) - } - - pub fn build_delete07(&self, conn: &Connection) -> Result { - let mut tombstone = Tombstone07::new(); + pub fn build_delete07(&self, conn: &Connection) -> Result { + let mut tombstone = Tombstone::new(); tombstone.set_id( self.ap_url .as_ref() @@ -264,7 +241,7 @@ impl Comment { .parse::()?, ); - let mut act = Delete07::new( + let mut act = Delete::new( self.get_author(conn)?.into_id().parse::()?, Base::retract(tombstone)?.into_generic()?, ); @@ -423,7 +400,7 @@ impl AsObject for Comment { } } -impl AsObject for Comment { +impl AsObject for Comment { type Error = Error; type Output = (); @@ -666,30 +643,6 @@ mod tests { }); } - #[test] - fn build_delete() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (comment, _posts, _users, _blogs) = prepare_activity(&conn); - let act = comment.build_delete(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "id": format!("https://plu.me/~/BlogName/testing/comment/{}#delete", comment.id), - "object": { - "id": format!("https://plu.me/~/BlogName/testing/comment/{}", comment.id), - "type": "Tombstone" - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Delete" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_delete07() { let conn = db(); diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 9739f2e4..84d72b22 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -11,7 +11,7 @@ use std::time::Duration; use crate::routes::errors::ErrorPage; use crate::template_utils::IntoContext; use plume_common::{ - activity_pub::{broadcast, broadcast07, ActivityStream, ApRequest}, + activity_pub::{broadcast07, ActivityStream, ApRequest}, utils, }; use plume_models::{ @@ -150,7 +150,7 @@ pub fn delete( if let Ok(comment) = Comment::get(&conn, id) { if comment.author_id == user.id { let dest = User::one_by_instance(&conn)?; - let delete_activity = comment.build_delete(&conn)?; + let delete_activity = comment.build_delete07(&conn)?; inbox( &conn, serde_json::to_value(&delete_activity).map_err(Error::from)?, @@ -158,7 +158,7 @@ pub fn delete( let user_c = user.clone(); rockets.worker.execute(move || { - broadcast(&user_c, delete_activity, dest, CONFIG.proxy().cloned()) + broadcast07(&user_c, delete_activity, dest, CONFIG.proxy().cloned()) }); rockets .worker From 771c157fe5a40ae76029e83c92e844be41b7107d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:30:18 +0900 Subject: [PATCH 168/233] Use Comment::to_activity07() instead of to_activity() --- plume-models/src/comments.rs | 84 ++++-------------------------------- src/routes/comments.rs | 4 +- 2 files changed, 10 insertions(+), 78 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 33da7d97..499f4a32 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -11,24 +11,23 @@ use crate::{ users::User, Connection, Error, Result, CONFIG, }; -use activitypub::{link, object::Note}; use activitystreams::{ - activity::{Create as Create07, Delete}, + activity::{Create, Delete}, base::{AnyBase, Base}, iri_string::types::IriString, - link::{self as link07, kind::MentionType}, + link::{self, kind::MentionType}, object::{Note as Note07, Tombstone}, prelude::*, primitives::OneOrMany, time::OffsetDateTime, }; -use chrono::{self, NaiveDateTime, TimeZone, Utc}; +use chrono::{self, NaiveDateTime}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Id, IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, + IntoId, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils, }; @@ -112,41 +111,6 @@ impl Comment { .unwrap_or(false) } - pub fn to_activity(&self, conn: &DbConn) -> Result { - let author = User::get(conn, self.author_id)?; - let (html, mentions, _hashtags) = utils::md_to_html( - self.content.get().as_ref(), - Some(&Instance::get_local()?.public_domain), - true, - Some(Media::get_media_processor(conn, vec![&author])), - ); - - let mut note = Note::default(); - let to = vec![Id::new(PUBLIC_VISIBILITY.to_string())]; - - note.object_props - .set_id_string(self.ap_url.clone().unwrap_or_default())?; - note.object_props - .set_summary_string(self.spoiler_text.clone())?; - note.object_props.set_content_string(html)?; - note.object_props - .set_in_reply_to_link(Id::new(self.in_response_to_id.map_or_else( - || Ok(Post::get(conn, self.post_id)?.ap_url), - |id| Ok(Comment::get(conn, id)?.ap_url.unwrap_or_default()) as Result, - )?))?; - note.object_props - .set_published_utctime(Utc.from_utc_datetime(&self.creation_date))?; - note.object_props.set_attributed_to_link(author.into_id())?; - note.object_props.set_to_link_vec(to)?; - note.object_props.set_tag_link_vec( - mentions - .into_iter() - .filter_map(|m| Mention::build_activity(conn, &m).ok()) - .collect::>(), - )?; - Ok(note) - } - pub fn to_activity07(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; let (html, mentions, _hashtags) = utils::md_to_html( @@ -185,13 +149,13 @@ impl Comment { Ok(note) } - pub fn create_activity07(&self, conn: &DbConn) -> Result { + pub fn create_activity07(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; let note = self.to_activity07(conn)?; let note_clone = note.clone(); - let mut act = Create07::new( + let mut act = Create::new( author.into_id().parse::()?, Base::retract(note)?.into_generic()?, ); @@ -329,7 +293,7 @@ impl FromId for Comment { if let Some(tags) = note.tag() { let author_url = &Post::get(conn, comm.post_id)?.get_authors(conn)?[0].ap_url; for tag in tags.iter() { - let m = tag.clone().extend::()?; // FIXME: Don't clone + let m = tag.clone().extend::()?; // FIXME: Don't clone if m.is_none() { continue; } @@ -390,7 +354,7 @@ impl FromId for Comment { } } -impl AsObject for Comment { +impl AsObject for Comment { type Error = Error; type Output = Self; @@ -579,38 +543,6 @@ mod tests { }) } - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (comment, _posts, _users, _blogs) = prepare_activity(&conn); - let act = comment.to_activity(&conn)?; - - let expected = json!({ - "attributedTo": "https://plu.me/@/admin/", - "content": r###"

My comment, mentioning to @user

-"###, - "id": format!("https://plu.me/~/BlogName/testing/comment/{}", comment.id), - "inReplyTo": "https://plu.me/~/BlogName/testing", - "published": format_datetime(&comment.creation_date), - "summary": "My CW", - "tag": [ - { - "href": "https://plu.me/@/user/", - "name": "@user", - "type": "Mention" - } - ], - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Note" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = db(); diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 84d72b22..e5d571f8 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -1,5 +1,5 @@ use crate::template_utils::Ructe; -use activitypub::object::Note; +use activitystreams::object::Note; use rocket::{ request::LenientForm, response::{Flash, Redirect}, @@ -187,7 +187,7 @@ pub fn activity_pub( conn: DbConn, ) -> Option> { Comment::get(&conn, id) - .and_then(|c| c.to_activity(&conn)) + .and_then(|c| c.to_activity07(&conn)) .ok() .map(ActivityStream::new) } From b13444895fe5789cdaab5e7cf198c05d14488583 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:34:19 +0900 Subject: [PATCH 169/233] Use Like::build_undo07() instead of build_undo() --- plume-models/src/likes.rs | 47 --------------------------------------- src/routes/likes.rs | 6 ++--- 2 files changed, 3 insertions(+), 50 deletions(-) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 0be2164b..38eb0f0f 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -87,22 +87,6 @@ impl Like { Ok(()) } - pub fn build_undo(&self, conn: &Connection) -> Result { - let mut act = activity::Undo::default(); - act.undo_props - .set_actor_link(User::get(conn, self.user_id)?.into_id())?; - act.undo_props.set_object_object(self.to_activity(conn)?)?; - act.object_props - .set_id_string(format!("{}#delete", self.ap_url))?; - act.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - act.object_props.set_cc_link_vec(vec![Id::new( - User::get(conn, self.user_id)?.followers_endpoint, - )])?; - - Ok(act) - } - pub fn build_undo07(&self, conn: &Connection) -> Result { let mut act = Undo07::new( User::get(conn, self.user_id)?.ap_url.parse::()?, @@ -273,37 +257,6 @@ mod tests { }); } - #[test] - fn build_undo() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (posts, _users, _blogs) = fill_database(&conn); - let post = &posts[0]; - let user = &post.get_authors(&conn)?[0]; - let like = Like::insert(&*conn, NewLike::new(post, user))?; - let act = like.build_undo(&*conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": "https://plu.me/@/admin/like/https://plu.me/~/BlogName/testing#delete", - "object": { - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": "https://plu.me/@/admin/like/https://plu.me/~/BlogName/testing", - "object": "https://plu.me/~/BlogName/testing", - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Like", - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Undo", - }); - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_undo07() { let conn = db(); diff --git a/src/routes/likes.rs b/src/routes/likes.rs index 25ca68bf..cda2dbfd 100644 --- a/src/routes/likes.rs +++ b/src/routes/likes.rs @@ -3,7 +3,7 @@ use rocket_i18n::I18n; use crate::routes::errors::ErrorPage; use crate::utils::requires_login; -use plume_common::activity_pub::broadcast; +use plume_common::activity_pub::{broadcast, broadcast07}; use plume_models::{ blogs::Blog, db_conn::DbConn, inbox::inbox, likes, posts::Post, timeline::*, users::User, Error, PlumeRocket, CONFIG, @@ -33,7 +33,7 @@ pub fn create( .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } else { let like = likes::Like::find_by_user_on_post(&conn, user.id, post.id)?; - let delete_act = like.build_undo(&conn)?; + let delete_act = like.build_undo07(&conn)?; inbox( &conn, serde_json::to_value(&delete_act).map_err(Error::from)?, @@ -42,7 +42,7 @@ pub fn create( let dest = User::one_by_instance(&conn)?; rockets .worker - .execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, delete_act, dest, CONFIG.proxy().cloned())); } Ok(Redirect::to(uri!( From 6ab1ecd57b29350405168e9bdb437e5eb9397f65 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:37:58 +0900 Subject: [PATCH 170/233] Use Like::to_activity07() instead of to_activity() --- plume-models/src/likes.rs | 51 ++++----------------------------------- src/routes/likes.rs | 6 ++--- 2 files changed, 8 insertions(+), 49 deletions(-) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 38eb0f0f..0218c8ee 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -2,9 +2,8 @@ use crate::{ db_conn::DbConn, instance::Instance, notifications::*, posts::Post, schema::likes, timeline::*, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::activity; use activitystreams::{ - activity::{ActorAndObjectRef, Like as Like07, Undo as Undo07}, + activity::{ActorAndObjectRef, Like as Like07, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -14,7 +13,7 @@ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Id, IntoId, PUBLIC_VISIBILITY, + PUBLIC_VISIBILITY, }; #[derive(Clone, Queryable, Identifiable)] @@ -40,22 +39,6 @@ impl Like { find_by!(likes, find_by_ap_url, ap_url as &str); find_by!(likes, find_by_user_on_post, user_id as i32, post_id as i32); - pub fn to_activity(&self, conn: &Connection) -> Result { - let mut act = activity::Like::default(); - act.like_props - .set_actor_link(User::get(conn, self.user_id)?.into_id())?; - act.like_props - .set_object_link(Post::get(conn, self.post_id)?.into_id())?; - act.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - act.object_props.set_cc_link_vec(vec![Id::new( - User::get(conn, self.user_id)?.followers_endpoint, - )])?; - act.object_props.set_id_string(self.ap_url.clone())?; - - Ok(act) - } - pub fn to_activity07(&self, conn: &Connection) -> Result { let mut act = Like07::new( User::get(conn, self.user_id)?.ap_url.parse::()?, @@ -87,8 +70,8 @@ impl Like { Ok(()) } - pub fn build_undo07(&self, conn: &Connection) -> Result { - let mut act = Undo07::new( + pub fn build_undo07(&self, conn: &Connection) -> Result { + let mut act = Undo::new( User::get(conn, self.user_id)?.ap_url.parse::()?, AnyBase::from_extended(self.to_activity07(conn)?)?, ); @@ -171,7 +154,7 @@ impl FromId for Like { } } -impl AsObject for Like { +impl AsObject for Like { type Error = Error; type Output = (); @@ -209,30 +192,6 @@ mod tests { use assert_json_diff::assert_json_eq; use serde_json::{json, to_value}; - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (posts, _users, _blogs) = fill_database(&conn); - let post = &posts[0]; - let user = &post.get_authors(&conn)?[0]; - let like = Like::insert(&*conn, NewLike::new(post, user))?; - let act = like.to_activity(&conn).unwrap(); - - let expected = json!({ - "actor": "https://plu.me/@/admin/", - "cc": ["https://plu.me/@/admin/followers"], - "id": "https://plu.me/@/admin/like/https://plu.me/~/BlogName/testing", - "object": "https://plu.me/~/BlogName/testing", - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Like", - }); - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = db(); diff --git a/src/routes/likes.rs b/src/routes/likes.rs index cda2dbfd..6ef57225 100644 --- a/src/routes/likes.rs +++ b/src/routes/likes.rs @@ -3,7 +3,7 @@ use rocket_i18n::I18n; use crate::routes::errors::ErrorPage; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast, broadcast07}; +use plume_common::activity_pub::broadcast07; use plume_models::{ blogs::Blog, db_conn::DbConn, inbox::inbox, likes, posts::Post, timeline::*, users::User, Error, PlumeRocket, CONFIG, @@ -27,10 +27,10 @@ pub fn create( Timeline::add_to_all_timelines(&conn, &post, Kind::Like(&user))?; let dest = User::one_by_instance(&*conn)?; - let act = like.to_activity(&*conn)?; + let act = like.to_activity07(&*conn)?; rockets .worker - .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); } else { let like = likes::Like::find_by_user_on_post(&conn, user.id, post.id)?; let delete_act = like.build_undo07(&conn)?; From 01dca62ce5d455052a830c9d5e0e6316d1cc36d2 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:38:32 +0900 Subject: [PATCH 171/233] Rename: Like07 -> LikeAct --- plume-models/src/likes.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 0218c8ee..e7787e57 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -3,7 +3,7 @@ use crate::{ users::User, Connection, Error, Result, CONFIG, }; use activitystreams::{ - activity::{ActorAndObjectRef, Like as Like07, Undo}, + activity::{ActorAndObjectRef, Like as LikeAct, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -39,8 +39,8 @@ impl Like { find_by!(likes, find_by_ap_url, ap_url as &str); find_by!(likes, find_by_user_on_post, user_id as i32, post_id as i32); - pub fn to_activity07(&self, conn: &Connection) -> Result { - let mut act = Like07::new( + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut act = LikeAct::new( User::get(conn, self.user_id)?.ap_url.parse::()?, Post::get(conn, self.post_id)?.ap_url.parse::()?, ); @@ -85,7 +85,7 @@ impl Like { } } -impl AsObject for Post { +impl AsObject for Post { type Error = Error; type Output = Like; @@ -107,13 +107,13 @@ impl AsObject for Post { impl FromId for Like { type Error = Error; - type Object = Like07; + type Object = LikeAct; fn from_db07(conn: &DbConn, id: &str) -> Result { Like::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, act: Like07) -> Result { + fn from_activity07(conn: &DbConn, act: LikeAct) -> Result { let res = Like::insert( conn, NewLike { From 5d08ff6c3b1fe6b7f74b2f9df0cadf0f46325f41 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:43:24 +0900 Subject: [PATCH 172/233] Use Mention::build_activity07() instead of build_activity() --- plume-models/src/mentions.rs | 29 ----------------------------- src/api/posts.rs | 4 ++-- src/routes/comments.rs | 4 ++-- src/routes/posts.rs | 5 +++-- 4 files changed, 7 insertions(+), 35 deletions(-) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 0d2fd415..7a3d0a87 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -61,14 +61,6 @@ impl Mention { } } - pub fn build_activity(conn: &DbConn, ment: &str) -> Result { - let user = User::find_by_fqn(conn, ment)?; - let mut mention = link::Mention::default(); - mention.link_props.set_href_string(user.ap_url)?; - mention.link_props.set_name_string(format!("@{}", ment))?; - Ok(mention) - } - pub fn build_activity07(conn: &DbConn, ment: &str) -> Result { let user = User::find_by_fqn(conn, ment)?; let mut mention = link07::Mention::new(); @@ -218,27 +210,6 @@ mod tests { use diesel::Connection; use serde_json::{json, to_value}; - #[test] - fn build_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (_posts, users, _blogs) = fill_database(&conn); - let user = &users[0]; - let name = &user.username; - let act = Mention::build_activity(&conn, name)?; - - let expected = json!({ - "href": "https://plu.me/@/admin/", - "name": "@admin", - "type": "Mention", - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_activity07() { let conn = db(); diff --git a/src/api/posts.rs b/src/api/posts.rs index a1dcb639..ca76e611 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -191,9 +191,9 @@ pub fn create( if post.published { for m in mentions.into_iter() { - Mention::from_activity( + Mention::from_activity07( &conn, - &Mention::build_activity(&conn, &m)?, + &Mention::build_activity07(&conn, &m)?, post.id, true, true, diff --git a/src/routes/comments.rs b/src/routes/comments.rs index e5d571f8..f7018139 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -71,9 +71,9 @@ pub fn create( // save mentions for ment in mentions { - Mention::from_activity( + Mention::from_activity07( &conn, - &Mention::build_activity(&conn, &ment) + &Mention::build_activity07(&conn, &ment) .expect("comments::create: build mention error"), comm.id, false, diff --git a/src/routes/posts.rs b/src/routes/posts.rs index ef76f1cf..61c3594c 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -530,9 +530,10 @@ pub fn create( if post.published { for m in mentions { - Mention::from_activity( + Mention::from_activity07( &conn, - &Mention::build_activity(&conn, &m).expect("post::create: mention build error"), + &Mention::build_activity07(&conn, &m) + .expect("post::create: mention build error"), post.id, true, true, From 4ef9350ce7b2b71f044d6668b9099781b56e2b2a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:45:06 +0900 Subject: [PATCH 173/233] Remove unused Mention::to_activity() --- plume-models/src/mentions.rs | 39 ------------------------------------ 1 file changed, 39 deletions(-) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 7a3d0a87..691b92d5 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -69,16 +69,6 @@ impl Mention { Ok(mention) } - pub fn to_activity(&self, conn: &Connection) -> Result { - let user = self.get_mentioned(conn)?; - let mut mention = link::Mention::default(); - mention.link_props.set_href_string(user.ap_url.clone())?; - mention - .link_props - .set_name_string(format!("@{}", user.fqn))?; - Ok(mention) - } - pub fn to_activity07(&self, conn: &Connection) -> Result { let user = self.get_mentioned(conn)?; let mut mention = link07::Mention::new(); @@ -231,35 +221,6 @@ mod tests { }); } - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (posts, users, _blogs) = fill_database(&conn); - let post = &posts[0]; - let user = &users[0]; - let mention = Mention::insert( - &conn, - NewMention { - mentioned_id: user.id, - post_id: Some(post.id), - comment_id: None, - }, - )?; - let act = mention.to_activity(&conn)?; - - let expected = json!({ - "href": "https://plu.me/@/admin/", - "name": "@admin", - "type": "Mention", - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = db(); From 41ccacc5d39c1385fbba427a74536ae0428f7a99 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:47:36 +0900 Subject: [PATCH 174/233] Remove unused Mention::from_activity() --- plume-models/src/mentions.rs | 56 ++++-------------------------------- 1 file changed, 6 insertions(+), 50 deletions(-) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 691b92d5..0e9a8ba0 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -2,11 +2,10 @@ use crate::{ comments::Comment, db_conn::DbConn, notifications::*, posts::Post, schema::mentions, users::User, Connection, Error, Result, }; -use activitypub::link; use activitystreams::{ base::BaseExt, iri_string::types::IriString, - link::{self as link07, LinkExt}, + link::{self, LinkExt}, }; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::inbox::AsActor; @@ -61,68 +60,25 @@ impl Mention { } } - pub fn build_activity07(conn: &DbConn, ment: &str) -> Result { + pub fn build_activity07(conn: &DbConn, ment: &str) -> Result { let user = User::find_by_fqn(conn, ment)?; - let mut mention = link07::Mention::new(); + let mut mention = link::Mention::new(); mention.set_href(user.ap_url.parse::()?); mention.set_name(format!("@{}", ment)); Ok(mention) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity07(&self, conn: &Connection) -> Result { let user = self.get_mentioned(conn)?; - let mut mention = link07::Mention::new(); + let mut mention = link::Mention::new(); mention.set_href(user.ap_url.parse::()?); mention.set_name(format!("@{}", user.fqn)); Ok(mention) } - pub fn from_activity( - conn: &Connection, - ment: &link::Mention, - inside: i32, - in_post: bool, - notify: bool, - ) -> Result { - let ap_url = ment.link_props.href_string().or(Err(Error::NotFound))?; - let mentioned = User::find_by_ap_url(conn, &ap_url)?; - - if in_post { - Post::get(conn, inside).and_then(|post| { - let res = Mention::insert( - conn, - NewMention { - mentioned_id: mentioned.id, - post_id: Some(post.id), - comment_id: None, - }, - )?; - if notify { - res.notify(conn)?; - } - Ok(res) - }) - } else { - Comment::get(conn, inside).and_then(|comment| { - let res = Mention::insert( - conn, - NewMention { - mentioned_id: mentioned.id, - post_id: None, - comment_id: Some(comment.id), - }, - )?; - if notify { - res.notify(conn)?; - } - Ok(res) - }) - } - } - pub fn from_activity07( conn: &Connection, - ment: &link07::Mention, + ment: &link::Mention, inside: i32, in_post: bool, notify: bool, From 7b3b00be23dca81a9a1986c03da22828d3b7398f Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:50:45 +0900 Subject: [PATCH 175/233] Remove unused Tag::from_activity() and to_activity() --- plume-models/src/tags.rs | 100 +-------------------------------------- 1 file changed, 1 insertion(+), 99 deletions(-) diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index c41700c9..2657b184 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -1,7 +1,7 @@ use crate::{ap_url, instance::Instance, schema::tags, Connection, Error, Result}; use activitystreams::iri_string::types::IriString; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; -use plume_common::activity_pub::{Hashtag, Hashtag07, HashtagExt}; +use plume_common::activity_pub::{Hashtag07, HashtagExt}; #[derive(Clone, Identifiable, Queryable)] pub struct Tag { @@ -25,17 +25,6 @@ impl Tag { find_by!(tags, find_by_name, tag as &str); list_by!(tags, for_post, post_id as i32); - pub fn to_activity(&self) -> Result { - let mut ht = Hashtag::default(); - ht.set_href_string(ap_url(&format!( - "{}/tag/{}", - Instance::get_local()?.public_domain, - self.tag - )))?; - ht.set_name_string(self.tag.clone())?; - Ok(ht) - } - pub fn to_activity07(&self) -> Result { let mut ht = Hashtag07::new(); ht.set_href( @@ -50,22 +39,6 @@ impl Tag { Ok(ht) } - pub fn from_activity( - conn: &Connection, - tag: &Hashtag, - post: i32, - is_hashtag: bool, - ) -> Result { - Tag::insert( - conn, - NewTag { - tag: tag.name_string()?, - is_hashtag, - post_id: post, - }, - ) - } - pub fn from_activity07( conn: &Connection, tag: &Hashtag07, @@ -82,17 +55,6 @@ impl Tag { ) } - pub fn build_activity(tag: String) -> Result { - let mut ht = Hashtag::default(); - ht.set_href_string(ap_url(&format!( - "{}/tag/{}", - Instance::get_local()?.public_domain, - tag - )))?; - ht.set_name_string(tag)?; - Ok(ht) - } - pub fn build_activity07(tag: String) -> Result { let mut ht = Hashtag07::new(); ht.set_href( @@ -123,48 +85,6 @@ mod tests { use assert_json_diff::assert_json_eq; use serde_json::to_value; - #[test] - fn to_activity() { - let conn = &db(); - conn.test_transaction::<_, Error, _>(|| { - fill_database(conn); - let tag = Tag { - id: 0, - tag: "a_tag".into(), - is_hashtag: false, - post_id: 0, - }; - let act = tag.to_activity()?; - let expected = json!({ - "href": "https://plu.me/tag/a_tag", - "name": "a_tag", - "type": "Hashtag" - }); - - assert_json_eq!(to_value(&act)?, expected); - - Ok(()) - }) - } - - #[test] - fn from_activity() { - let conn = &db(); - conn.test_transaction::<_, Error, _>(|| { - let (posts, _users, _blogs) = fill_database(conn); - let post_id = posts[0].id; - let mut ht = Hashtag::default(); - ht.set_href_string(ap_url(&format!("https://plu.me/tag/a_tag")))?; - ht.set_name_string("a_tag".into())?; - let tag = Tag::from_activity(conn, &ht, post_id, true)?; - - assert_eq!(&tag.tag, "a_tag"); - assert!(tag.is_hashtag); - - Ok(()) - }); - } - #[test] fn from_activity07() { let conn = &db(); @@ -183,24 +103,6 @@ mod tests { }); } - #[test] - fn build_activity() { - let conn = &db(); - conn.test_transaction::<_, Error, _>(|| { - fill_database(conn); - let act = Tag::build_activity("a_tag".into())?; - let expected = json!({ - "href": "https://plu.me/tag/a_tag", - "name": "a_tag", - "type": "Hashtag" - }); - - assert_json_eq!(to_value(&act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = &db(); From 68c794c54b10a48cc26ae5cb1c25025629414a77 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:55:18 +0900 Subject: [PATCH 176/233] Use User::outbox_page07() instead of outbox_page() --- plume-models/src/users.rs | 69 +++------------------------------------ src/routes/user.rs | 5 +-- 2 files changed, 8 insertions(+), 66 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 32b3729e..4967892f 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -7,7 +7,7 @@ use crate::{ use activitypub::{ activity::Delete, actor::Person, - collection::{OrderedCollection, OrderedCollectionPage}, + collection::OrderedCollection, object::{Image, Tombstone}, Activity, CustomObject, Endpoint, }; @@ -16,9 +16,7 @@ use activitystreams::{ actor::{ApActor, AsApActor}, actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, base::{AnyBase, Base}, - collection::{ - OrderedCollection as OrderedCollection07, OrderedCollectionPage as OrderedCollectionPage07, - }, + collection::{OrderedCollection as OrderedCollection07, OrderedCollectionPage}, iri_string::types::IriString, markers::Activity as Activity07, object::{kind::ImageType, AsObject as _, Image as Image07, Tombstone as Tombstone07}, @@ -505,59 +503,23 @@ impl User { coll.set_total_items(self.get_activities_count(conn) as u64); Ok(coll) } - pub fn outbox_page( + pub fn outbox_page07( &self, conn: &Connection, (min, max): (i32, i32), ) -> Result> { - Ok(ActivityStream::new( - self.outbox_collection_page(conn, (min, max))?, - )) - } - pub fn outbox_page07( - &self, - conn: &Connection, - (min, max): (i32, i32), - ) -> Result> { Ok(ActivityStream::new( self.outbox_collection_page07(conn, (min, max))?, )) } - pub fn outbox_collection_page( + pub fn outbox_collection_page07( &self, conn: &Connection, (min, max): (i32, i32), ) -> Result { let acts = self.get_activities_page(conn, (min, max))?; let n_acts = self.get_activities_count(conn); - let mut coll = OrderedCollectionPage::default(); - if n_acts - i64::from(min) >= i64::from(ITEMS_PER_PAGE) { - coll.collection_page_props.set_next_link(Id::new(&format!( - "{}?page={}", - &self.outbox_url, - min / ITEMS_PER_PAGE + 2 - )))?; - } - if min > 0 { - coll.collection_page_props.set_prev_link(Id::new(&format!( - "{}?page={}", - &self.outbox_url, - min / ITEMS_PER_PAGE - )))?; - } - coll.collection_props.items = serde_json::to_value(acts)?; - coll.collection_page_props - .set_part_of_link(Id::new(&self.outbox_url))?; - Ok(coll) - } - pub fn outbox_collection_page07( - &self, - conn: &Connection, - (min, max): (i32, i32), - ) -> Result { - let acts = self.get_activities_page(conn, (min, max))?; - let n_acts = self.get_activities_count(conn); - let mut coll = OrderedCollectionPage07::new(); + let mut coll = OrderedCollectionPage::new(); if n_acts - i64::from(min) >= i64::from(ITEMS_PER_PAGE) { coll.set_next( format!("{}?page={}", &self.outbox_url, min / ITEMS_PER_PAGE + 2) @@ -1851,27 +1813,6 @@ pub(crate) mod tests { }); } - #[test] - fn outbox_collection_page() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let users = fill_database(&conn); - let user = &users[0]; - let act = user.outbox_collection_page(&conn, (33, 36))?; - - let expected = json!({ - "items": [], - "partOf": "https://plu.me/@/admin/outbox", - "prev": "https://plu.me/@/admin/outbox?page=2", - "type": "OrderedCollectionPage", - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn outbox_collection_page07() { let conn = db(); diff --git a/src/routes/user.rs b/src/routes/user.rs index 576fc3c6..a5d42dda 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -1,4 +1,5 @@ -use activitypub::collection::{OrderedCollection, OrderedCollectionPage}; +use activitypub::collection::OrderedCollection; +use activitystreams::collection::OrderedCollectionPage; use diesel::SaveChangesDsl; use rocket::{ http::{uri::Uri, ContentType, Cookies}, @@ -537,7 +538,7 @@ pub fn outbox_page( conn: DbConn, ) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; - user.outbox_page(&conn, page.limits()).ok() + user.outbox_page07(&conn, page.limits()).ok() } #[post("/@//inbox", data = "")] pub fn inbox( From fd341bdb22e778afeedd2f09363144c26a879a2c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 2 May 2022 23:57:42 +0900 Subject: [PATCH 177/233] Use User::outbox07() instead of outbox() --- plume-models/src/users.rs | 40 --------------------------------------- src/routes/user.rs | 8 +++++--- 2 files changed, 5 insertions(+), 43 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 4967892f..343f61ef 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -7,7 +7,6 @@ use crate::{ use activitypub::{ activity::Delete, actor::Person, - collection::OrderedCollection, object::{Image, Tombstone}, Activity, CustomObject, Endpoint, }; @@ -470,26 +469,9 @@ impl User { .load::(conn) .map_err(Error::from) } - pub fn outbox(&self, conn: &Connection) -> Result> { - Ok(ActivityStream::new(self.outbox_collection(conn)?)) - } pub fn outbox07(&self, conn: &Connection) -> Result> { Ok(ActivityStream::new(self.outbox_collection07(conn)?)) } - pub fn outbox_collection(&self, conn: &Connection) -> Result { - let mut coll = OrderedCollection::default(); - let first = &format!("{}?page=1", &self.outbox_url); - let last = &format!( - "{}?page={}", - &self.outbox_url, - self.get_activities_count(conn) / i64::from(ITEMS_PER_PAGE) + 1 - ); - coll.collection_props.set_first_link(Id::new(first))?; - coll.collection_props.set_last_link(Id::new(last))?; - coll.collection_props - .set_total_items_u64(self.get_activities_count(conn) as u64)?; - Ok(coll) - } pub fn outbox_collection07(&self, conn: &Connection) -> Result { let mut coll = OrderedCollection07::new(); let first = &format!("{}?page=1", &self.outbox_url); @@ -1770,28 +1752,6 @@ pub(crate) mod tests { }); } - #[test] - fn outbox_collection() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (_pages, users, _blogs) = fill_pages(&conn); - let user = &users[0]; - let act = user.outbox_collection(&conn)?; - - let expected = json!({ - "first": "https://plu.me/@/admin/outbox?page=1", - "items": null, - "last": "https://plu.me/@/admin/outbox?page=5", - "totalItems": 51, - "type": "OrderedCollection", - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn outbox_collection07() { let conn = db(); diff --git a/src/routes/user.rs b/src/routes/user.rs index a5d42dda..da5b1a19 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -1,5 +1,7 @@ use activitypub::collection::OrderedCollection; -use activitystreams::collection::OrderedCollectionPage; +use activitystreams::collection::{ + OrderedCollection as OrderedCollection07, OrderedCollectionPage, +}; use diesel::SaveChangesDsl; use rocket::{ http::{uri::Uri, ContentType, Cookies}, @@ -527,9 +529,9 @@ pub fn create( } #[get("/@//outbox")] -pub fn outbox(name: String, conn: DbConn) -> Option> { +pub fn outbox(name: String, conn: DbConn) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; - user.outbox(&conn).ok() + user.outbox07(&conn).ok() } #[get("/@//outbox?")] pub fn outbox_page( From effdc44943aa4f55744d8596fef0414b78fc6866 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:03:11 +0900 Subject: [PATCH 178/233] Use User::delete_activity07() instead of delete_activity() --- plume-models/src/users.rs | 68 ++++----------------------------------- src/routes/instance.rs | 6 ++-- src/routes/user.rs | 6 ++-- 3 files changed, 13 insertions(+), 67 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 343f61ef..f9075779 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -4,21 +4,16 @@ use crate::{ safe_string::SafeString, schema::users, timeline::Timeline, Connection, Error, Result, UserEvent::*, CONFIG, ITEMS_PER_PAGE, USER_CHAN, }; -use activitypub::{ - activity::Delete, - actor::Person, - object::{Image, Tombstone}, - Activity, CustomObject, Endpoint, -}; +use activitypub::{actor::Person, object::Image, Activity, CustomObject, Endpoint}; use activitystreams::{ - activity::Delete as Delete07, + activity::Delete, actor::{ApActor, AsApActor}, actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, base::{AnyBase, Base}, collection::{OrderedCollection as OrderedCollection07, OrderedCollectionPage}, iri_string::types::IriString, markers::Activity as Activity07, - object::{kind::ImageType, AsObject as _, Image as Image07, Tombstone as Tombstone07}, + object::{kind::ImageType, AsObject as _, Image as Image07, Tombstone}, prelude::*, }; use chrono::{NaiveDateTime, Utc}; @@ -917,34 +912,11 @@ impl User { Ok(CustomPerson07::new(actor, ap_signature)) } - pub fn delete_activity(&self, conn: &Connection) -> Result { - let mut del = Delete::default(); - - let mut tombstone = Tombstone::default(); - tombstone.object_props.set_id_string(self.ap_url.clone())?; - - del.delete_props - .set_actor_link(Id::new(self.ap_url.clone()))?; - del.delete_props.set_object_object(tombstone)?; - del.object_props - .set_id_string(format!("{}#delete", self.ap_url))?; - del.object_props - .set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?; - del.object_props.set_cc_link_vec( - self.get_followers(conn)? - .into_iter() - .map(|f| Id::new(f.ap_url)) - .collect(), - )?; - - Ok(del) - } - - pub fn delete_activity07(&self, conn: &Connection) -> Result { - let mut tombstone = Tombstone07::new(); + pub fn delete_activity07(&self, conn: &Connection) -> Result { + let mut tombstone = Tombstone::new(); tombstone.set_id(self.ap_url.parse()?); - let mut del = Delete07::new( + let mut del = Delete::new( self.ap_url.parse::()?, Base::retract(tombstone)?.into_generic()?, ); @@ -1192,7 +1164,7 @@ impl AsActor<&DbConn> for User { } } -impl AsObject for User { +impl AsObject for User { type Error = Error; type Output = (); @@ -1700,32 +1672,6 @@ pub(crate) mod tests { }); } - #[test] - fn delete_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let users = fill_database(&conn); - let user = &users[1]; - let act = user.delete_activity(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/user/", - "cc": [], - "id": "https://plu.me/@/user/#delete", - "object": { - "id": "https://plu.me/@/user/", - "type": "Tombstone", - }, - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "type": "Delete", - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn delete_activity07() { let conn = db(); diff --git a/src/routes/instance.rs b/src/routes/instance.rs index cedaa900..3864f20c 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -11,7 +11,7 @@ use validator::{Validate, ValidationErrors}; use crate::inbox; use crate::routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page, RespondOrRedirect}; use crate::template_utils::{IntoContext, Ructe}; -use plume_common::activity_pub::{broadcast, inbox::FromId}; +use plume_common::activity_pub::{broadcast07, inbox::FromId}; use plume_models::{ admin::*, blocklisted_emails::*, @@ -382,8 +382,8 @@ fn ban(id: i32, conn: &Connection, worker: &ScheduledThreadPool) -> Result<(), E ) .unwrap(); let target = User::one_by_instance(&*conn)?; - let delete_act = u.delete_activity(&*conn)?; - worker.execute(move || broadcast(&u, delete_act, target, CONFIG.proxy().cloned())); + let delete_act = u.delete_activity07(&*conn)?; + worker.execute(move || broadcast07(&u, delete_act, target, CONFIG.proxy().cloned())); } Ok(()) diff --git a/src/routes/user.rs b/src/routes/user.rs index da5b1a19..99315697 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -18,7 +18,7 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast, ActivityStream, ApRequest, Id}; +use plume_common::activity_pub::{broadcast, broadcast07, ActivityStream, ApRequest, Id}; use plume_common::utils::md_to_html; use plume_models::{ blogs::Blog, @@ -386,10 +386,10 @@ pub fn delete( account.delete(&conn)?; let target = User::one_by_instance(&conn)?; - let delete_act = account.delete_activity(&conn)?; + let delete_act = account.delete_activity07(&conn)?; rockets .worker - .execute(move || broadcast(&account, delete_act, target, CONFIG.proxy().cloned())); + .execute(move || broadcast07(&account, delete_act, target, CONFIG.proxy().cloned())); if let Some(cookie) = cookies.get_private(AUTH_COOKIE) { cookies.remove_private(cookie); From e41fa353e44bc95e5fc93777d7dcaa589fd0070c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:06:18 +0900 Subject: [PATCH 179/233] Use User::to_activity07() instead of to_activity() --- plume-models/src/users.rs | 128 +++----------------------------------- src/routes/user.rs | 6 +- 2 files changed, 12 insertions(+), 122 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index f9075779..1aee57b1 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -4,16 +4,16 @@ use crate::{ safe_string::SafeString, schema::users, timeline::Timeline, Connection, Error, Result, UserEvent::*, CONFIG, ITEMS_PER_PAGE, USER_CHAN, }; -use activitypub::{actor::Person, object::Image, Activity, CustomObject, Endpoint}; +use activitypub::{actor::Person, Activity, CustomObject}; use activitystreams::{ activity::Delete, actor::{ApActor, AsApActor}, - actor::{ApActor as ApActor07, Endpoints as Endpoints07, Person as Person07}, + actor::{ApActor as ApActor07, Endpoints, Person as Person07}, base::{AnyBase, Base}, collection::{OrderedCollection as OrderedCollection07, OrderedCollectionPage}, iri_string::types::IriString, markers::Activity as Activity07, - object::{kind::ImageType, AsObject as _, Image as Image07, Tombstone}, + object::{kind::ImageType, AsObject as _, Image, Tombstone}, prelude::*, }; use chrono::{NaiveDateTime, Utc}; @@ -31,7 +31,7 @@ use plume_common::{ request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, - PublicKey, PublicKey07, ToAsString, ToAsUri, PUBLIC_VISIBILITY, + PublicKey07, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils, }; @@ -282,7 +282,7 @@ impl User { .next() .and_then(|i| { i.clone() - .extend::() // FIXME: Don't clone() + .extend::() // FIXME: Don't clone() .ok()? .and_then(|url| Some(url.id_unchecked()?.to_string())) }) @@ -827,53 +827,6 @@ impl User { } } - pub fn to_activity(&self, conn: &Connection) -> Result { - let mut actor = Person::default(); - actor.object_props.set_id_string(self.ap_url.clone())?; - actor - .object_props - .set_name_string(self.display_name.clone())?; - actor - .object_props - .set_summary_string(self.summary_html.get().clone())?; - actor.object_props.set_url_string(self.ap_url.clone())?; - actor - .ap_actor_props - .set_inbox_string(self.inbox_url.clone())?; - actor - .ap_actor_props - .set_outbox_string(self.outbox_url.clone())?; - actor - .ap_actor_props - .set_preferred_username_string(self.username.clone())?; - actor - .ap_actor_props - .set_followers_string(self.followers_endpoint.clone())?; - - if let Some(shared_inbox_url) = self.shared_inbox_url.clone() { - let mut endpoints = Endpoint::default(); - endpoints.set_shared_inbox_string(shared_inbox_url)?; - actor.ap_actor_props.set_endpoints_endpoint(endpoints)?; - } - - let mut public_key = PublicKey::default(); - public_key.set_id_string(format!("{}#main-key", self.ap_url))?; - public_key.set_owner_string(self.ap_url.clone())?; - public_key.set_public_key_pem_string(self.public_key.clone())?; - let mut ap_signature = ApSignature::default(); - ap_signature.set_public_key_publickey(public_key)?; - - if let Some(avatar_id) = self.avatar_id { - let mut avatar = Image::default(); - avatar - .object_props - .set_url_string(Media::get(conn, avatar_id)?.url()?)?; - actor.object_props.set_icon_object(avatar)?; - } - - Ok(CustomPerson::new(actor, ap_signature)) - } - pub fn to_activity07(&self, conn: &Connection) -> Result { let mut actor = ApActor07::new(self.inbox_url.parse()?, Person07::new()); let ap_url = self.ap_url.parse::()?; @@ -887,9 +840,9 @@ impl User { actor.set_followers(self.followers_endpoint.parse()?); if let Some(shared_inbox_url) = self.shared_inbox_url.clone() { - let endpoints = Endpoints07 { + let endpoints = Endpoints { shared_inbox: Some(shared_inbox_url.parse::()?), - ..Endpoints07::default() + ..Endpoints::default() }; actor.set_endpoints(endpoints); } @@ -904,7 +857,7 @@ impl User { }; if let Some(avatar_id) = self.avatar_id { - let mut avatar = Image07::new(); + let mut avatar = Image::new(); avatar.set_url(Media::get(conn, avatar_id)?.url()?.parse::()?); actor.set_icon(avatar.into_any_base()?); } @@ -1545,71 +1498,6 @@ pub(crate) mod tests { }); } - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let users = fill_database(&conn); - let user = &users[0]; - let act = user.to_activity(&conn)?; - - let expected = json!({ - "endpoints": { - "sharedInbox": "https://plu.me/inbox" - }, - "followers": "https://plu.me/@/admin/followers", - "following": null, - "id": "https://plu.me/@/admin/", - "inbox": "https://plu.me/@/admin/inbox", - "liked": null, - "name": "The admin", - "outbox": "https://plu.me/@/admin/outbox", - "preferredUsername": "admin", - "publicKey": { - "id": "https://plu.me/@/admin/#main-key", - "owner": "https://plu.me/@/admin/", - "publicKeyPem": user.public_key, - }, - "summary": "

Hello there, I’m the admin

\n", - "type": "Person", - "url": "https://plu.me/@/admin/" - }); - - assert_json_eq!(to_value(act)?, expected); - - let other = &users[2]; - let other_act = other.to_activity(&conn)?; - let expected_other = json!({ - "endpoints": { - "sharedInbox": "https://plu.me/inbox" - }, - "followers": "https://plu.me/@/other/followers", - "following": null, - "icon": { - "url": "https://plu.me/static/media/example.png", - "type": "Image", - }, - "id": "https://plu.me/@/other/", - "inbox": "https://plu.me/@/other/inbox", - "liked": null, - "name": "Another user", - "outbox": "https://plu.me/@/other/outbox", - "preferredUsername": "other", - "publicKey": { - "id": "https://plu.me/@/other/#main-key", - "owner": "https://plu.me/@/other/", - "publicKeyPem": other.public_key, - }, - "summary": "

Hello there, I’m someone else

\n", - "type": "Person", - "url": "https://plu.me/@/other/" - }); - - assert_json_eq!(to_value(other_act)?, expected_other); - - Ok(()) - }); - } #[test] fn to_activity07() { let conn = db(); diff --git a/src/routes/user.rs b/src/routes/user.rs index 99315697..e89f2d04 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -18,7 +18,9 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast, broadcast07, ActivityStream, ApRequest, Id}; +use plume_common::activity_pub::{ + broadcast, broadcast07, ActivityStream, ApRequest, CustomPerson, Id, +}; use plume_common::utils::md_to_html; use plume_models::{ blogs::Blog, @@ -271,7 +273,7 @@ pub fn activity_details( _ap: ApRequest, ) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; - Some(ActivityStream::new(user.to_activity(&conn).ok()?)) + Some(ActivityStream::new(user.to_activity07(&conn).ok()?)) } #[get("/users/new")] From 2fe2505a017d9276dde0712f42c13224eccfd946 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:09:15 +0900 Subject: [PATCH 180/233] Remove unused Hashtag --- plume-common/src/activity_pub/mod.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 5edab856..755d4e17 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -372,23 +372,6 @@ where pub type CustomPerson = Ext1, ApSignature07>; pub type CustomGroup = Ext2, ApSignature07, SourceProperty>; -#[derive(Clone, Debug, Default, UnitString)] -#[activitystreams(Hashtag)] -pub struct HashtagType; - -#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] -#[serde(rename_all = "camelCase")] -pub struct Hashtag { - #[serde(rename = "type")] - kind: HashtagType, - - #[activitystreams(concrete(String), functional)] - pub href: Option, - - #[activitystreams(concrete(String), functional)] - pub name: Option, -} - kind!(HashtagType07, Hashtag); #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] From f8870af9fe809d84248f4745c7eea21145292388 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:10:51 +0900 Subject: [PATCH 181/233] Remove trailing 07 from Hashtag --- plume-common/src/activity_pub/mod.rs | 30 ++++++++++++++-------------- plume-models/src/posts.rs | 10 +++++----- plume-models/src/tags.rs | 14 ++++++------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 755d4e17..bdfa26ef 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -372,10 +372,10 @@ where pub type CustomPerson = Ext1, ApSignature07>; pub type CustomGroup = Ext2, ApSignature07, SourceProperty>; -kind!(HashtagType07, Hashtag); +kind!(HashtagType, Hashtag); #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -pub struct Hashtag07 { +pub struct Hashtag { #[serde(skip_serializing_if = "Option::is_none")] pub href: Option, @@ -383,10 +383,10 @@ pub struct Hashtag07 { pub name: Option, #[serde(flatten)] - inner: Object07, + inner: Object07, } -impl Hashtag07 { +impl Hashtag { pub fn new() -> Self { Self { href: None, @@ -395,14 +395,14 @@ impl Hashtag07 { } } - pub fn extending(mut inner: Object07) -> Result { + pub fn extending(mut inner: Object07) -> Result { let href = inner.remove("href")?; let name = inner.remove("name")?; Ok(Self { href, name, inner }) } - pub fn retracting(self) -> Result, serde_json::Error> { + pub fn retracting(self) -> Result, serde_json::Error> { let Self { href, name, @@ -416,9 +416,9 @@ impl Hashtag07 { } pub trait AsHashtag: markers::Object { - fn hashtag_ref(&self) -> &Hashtag07; + fn hashtag_ref(&self) -> &Hashtag; - fn hashtag_mut(&mut self) -> &mut Hashtag07; + fn hashtag_mut(&mut self) -> &mut Hashtag; } pub trait HashtagExt: AsHashtag { @@ -465,13 +465,13 @@ pub trait HashtagExt: AsHashtag { } } -impl Default for Hashtag07 { +impl Default for Hashtag { fn default() -> Self { Self::new() } } -impl AsHashtag for Hashtag07 { +impl AsHashtag for Hashtag { fn hashtag_ref(&self) -> &Self { self } @@ -481,22 +481,22 @@ impl AsHashtag for Hashtag07 { } } -impl Extends for Hashtag07 { +impl Extends for Hashtag { type Error = serde_json::Error; - fn extends(base: Base) -> Result { + fn extends(base: Base) -> Result { let inner = Object07::extends(base)?; Self::extending(inner) } - fn retracts(self) -> Result, Self::Error> { + fn retracts(self) -> Result, Self::Error> { let inner = self.retracting()?; inner.retracts() } } -impl markers::Base for Hashtag07 {} -impl markers::Object for Hashtag07 {} +impl markers::Base for Hashtag {} +impl markers::Object for Hashtag {} impl HashtagExt for T where T: AsHashtag {} #[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 2977a661..c6206e65 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -23,7 +23,7 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag07, HashtagType07, Id, IntoId, Licensed, Licensed07, + Hashtag, HashtagType, Id, IntoId, Licensed, Licensed07, LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, @@ -494,7 +494,7 @@ impl Post { Ok(()) } - pub fn update_tags07(&self, conn: &Connection, tags: Vec) -> Result<()> { + pub fn update_tags07(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() .filter_map(|t| t.name.as_ref().map(|name| name.as_str().to_string())) @@ -531,7 +531,7 @@ impl Post { Ok(()) } - pub fn update_hashtags07(&self, conn: &Connection, tags: Vec) -> Result<()> { + pub fn update_hashtags07(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() .filter_map(|t| t.name.as_ref().map(|name| name.as_str().to_string())) @@ -797,7 +797,7 @@ impl FromId for Post { .ok(); tag.clone() - .extend::() // FIXME: Don't clone + .extend::() // FIXME: Don't clone .map(|hashtag| { hashtag.and_then(|t| { let tag_name = t.name.clone()?.as_str().to_string(); @@ -962,7 +962,7 @@ impl AsObject for PostUpdate { .map(|m| mentions.push(m)) .ok(); - serde_json::from_value::(tag.clone()) + serde_json::from_value::(tag.clone()) .map_err(Error::from) .and_then(|t| { let tag_name = t.name.as_ref().ok_or(Error::MissingApProperty)?; diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index 2657b184..eb24f0c0 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -1,7 +1,7 @@ use crate::{ap_url, instance::Instance, schema::tags, Connection, Error, Result}; use activitystreams::iri_string::types::IriString; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; -use plume_common::activity_pub::{Hashtag07, HashtagExt}; +use plume_common::activity_pub::{Hashtag, HashtagExt}; #[derive(Clone, Identifiable, Queryable)] pub struct Tag { @@ -25,8 +25,8 @@ impl Tag { find_by!(tags, find_by_name, tag as &str); list_by!(tags, for_post, post_id as i32); - pub fn to_activity07(&self) -> Result { - let mut ht = Hashtag07::new(); + pub fn to_activity07(&self) -> Result { + let mut ht = Hashtag::new(); ht.set_href( ap_url(&format!( "{}/tag/{}", @@ -41,7 +41,7 @@ impl Tag { pub fn from_activity07( conn: &Connection, - tag: &Hashtag07, + tag: &Hashtag, post: i32, is_hashtag: bool, ) -> Result { @@ -55,8 +55,8 @@ impl Tag { ) } - pub fn build_activity07(tag: String) -> Result { - let mut ht = Hashtag07::new(); + pub fn build_activity07(tag: String) -> Result { + let mut ht = Hashtag::new(); ht.set_href( ap_url(&format!( "{}/tag/{}", @@ -91,7 +91,7 @@ mod tests { conn.test_transaction::<_, Error, _>(|| { let (posts, _users, _blogs) = fill_database(conn); let post_id = posts[0].id; - let mut ht = Hashtag07::new(); + let mut ht = Hashtag::new(); ht.set_href(ap_url(&format!("https://plu.me/tag/a_tag")).parse::()?); ht.set_name("a_tag".to_string()); let tag = Tag::from_activity07(conn, &ht, post_id, true)?; From 6c615d01ad5c6091f4464264ebf82014a3168437 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:15:46 +0900 Subject: [PATCH 182/233] Remove users::CustomPerson --- plume-models/src/users.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 1aee57b1..11db86a5 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -4,11 +4,11 @@ use crate::{ safe_string::SafeString, schema::users, timeline::Timeline, Connection, Error, Result, UserEvent::*, CONFIG, ITEMS_PER_PAGE, USER_CHAN, }; -use activitypub::{actor::Person, Activity, CustomObject}; +use activitypub::Activity; use activitystreams::{ activity::Delete, actor::{ApActor, AsApActor}, - actor::{ApActor as ApActor07, Endpoints, Person as Person07}, + actor::{ApActor as ApActor07, Endpoints, Person}, base::{AnyBase, Base}, collection::{OrderedCollection as OrderedCollection07, OrderedCollectionPage}, iri_string::types::IriString, @@ -30,8 +30,8 @@ use plume_common::{ inbox::{AsActor, AsObject, FromId}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, - ActivityStream, ApSignature, ApSignature07, CustomPerson as CustomPerson07, Id, IntoId, - PublicKey07, ToAsString, ToAsUri, PUBLIC_VISIBILITY, + ActivityStream, ApSignature07, CustomPerson, Id, IntoId, PublicKey07, ToAsString, ToAsUri, + PUBLIC_VISIBILITY, }, utils, }; @@ -47,8 +47,6 @@ use std::{ }; use webfinger::*; -pub type CustomPerson = CustomObject; - pub enum Role { Admin = 0, Moderator = 1, @@ -247,13 +245,13 @@ impl User { .ok_or(Error::Webfinger) } - fn fetch(url: &str) -> Result { + fn fetch(url: &str) -> Result { let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; let text = &res.text()?; // without this workaround, publicKey is not correctly deserialized let ap_sign = serde_json::from_str::(text)?; - let person = serde_json::from_str::(text)?; - let json = CustomPerson07::new( + let person = serde_json::from_str::(text)?; + let json = CustomPerson::new( ApActor::new( person .clone() @@ -827,8 +825,8 @@ impl User { } } - pub fn to_activity07(&self, conn: &Connection) -> Result { - let mut actor = ApActor07::new(self.inbox_url.parse()?, Person07::new()); + pub fn to_activity07(&self, conn: &Connection) -> Result { + let mut actor = ApActor07::new(self.inbox_url.parse()?, Person::new()); let ap_url = self.ap_url.parse::()?; actor.set_id(ap_url.clone()); actor.set_name(self.display_name.clone()); @@ -862,7 +860,7 @@ impl User { actor.set_icon(avatar.into_any_base()?); } - Ok(CustomPerson07::new(actor, ap_signature)) + Ok(CustomPerson::new(actor, ap_signature)) } pub fn delete_activity07(&self, conn: &Connection) -> Result { @@ -998,13 +996,13 @@ impl Eq for User {} impl FromId for User { type Error = Error; - type Object = CustomPerson07; + type Object = CustomPerson; fn from_db07(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, acct: CustomPerson07) -> Result { + fn from_activity07(conn: &DbConn, acct: CustomPerson) -> Result { let actor = acct.ap_actor_ref(); let username = actor .preferred_username() From 6d919da0490ab947d0180361d6b5c106ded44762 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:17:19 +0900 Subject: [PATCH 183/233] Remove duplicate import --- plume-models/src/users.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 11db86a5..a6da8287 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -7,8 +7,7 @@ use crate::{ use activitypub::Activity; use activitystreams::{ activity::Delete, - actor::{ApActor, AsApActor}, - actor::{ApActor as ApActor07, Endpoints, Person}, + actor::{ApActor, AsApActor, Endpoints, Person}, base::{AnyBase, Base}, collection::{OrderedCollection as OrderedCollection07, OrderedCollectionPage}, iri_string::types::IriString, @@ -826,7 +825,7 @@ impl User { } pub fn to_activity07(&self, conn: &Connection) -> Result { - let mut actor = ApActor07::new(self.inbox_url.parse()?, Person::new()); + let mut actor = ApActor::new(self.inbox_url.parse()?, Person::new()); let ap_url = self.ap_url.parse::()?; actor.set_id(ap_url.clone()); actor.set_name(self.display_name.clone()); From ee97213c90eb8fcfa1b648f87fc2262fc6fcab7c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:18:42 +0900 Subject: [PATCH 184/233] Remove trailing 07 from import of OrderedCollectionPage --- plume-models/src/users.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index a6da8287..f0daac60 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -9,7 +9,7 @@ use activitystreams::{ activity::Delete, actor::{ApActor, AsApActor, Endpoints, Person}, base::{AnyBase, Base}, - collection::{OrderedCollection as OrderedCollection07, OrderedCollectionPage}, + collection::{OrderedCollection, OrderedCollectionPage}, iri_string::types::IriString, markers::Activity as Activity07, object::{kind::ImageType, AsObject as _, Image, Tombstone}, @@ -461,11 +461,11 @@ impl User { .load::(conn) .map_err(Error::from) } - pub fn outbox07(&self, conn: &Connection) -> Result> { + pub fn outbox07(&self, conn: &Connection) -> Result> { Ok(ActivityStream::new(self.outbox_collection07(conn)?)) } - pub fn outbox_collection07(&self, conn: &Connection) -> Result { - let mut coll = OrderedCollection07::new(); + pub fn outbox_collection07(&self, conn: &Connection) -> Result { + let mut coll = OrderedCollection::new(); let first = &format!("{}?page=1", &self.outbox_url); let last = &format!( "{}?page={}", From 0ad845e0f7c6025e6dbaad5740234506022d479f Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:22:22 +0900 Subject: [PATCH 185/233] Remove unused User::fetch_outbox() --- plume-models/src/users.rs | 55 +++------------------------------------ 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index f0daac60..0677a09a 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -4,14 +4,13 @@ use crate::{ safe_string::SafeString, schema::users, timeline::Timeline, Connection, Error, Result, UserEvent::*, CONFIG, ITEMS_PER_PAGE, USER_CHAN, }; -use activitypub::Activity; use activitystreams::{ activity::Delete, actor::{ApActor, AsApActor, Endpoints, Person}, base::{AnyBase, Base}, collection::{OrderedCollection, OrderedCollectionPage}, iri_string::types::IriString, - markers::Activity as Activity07, + markers::Activity, object::{kind::ImageType, AsObject as _, Image, Tombstone}, prelude::*, }; @@ -513,21 +512,8 @@ impl User { coll.set_part_of(self.outbox_url.parse::()?); Ok(coll) } - fn fetch_outbox_page(&self, url: &str) -> Result<(Vec, Option)> { - let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; - let text = &res.text()?; - let json: serde_json::Value = serde_json::from_str(text)?; - let items = json["items"] - .as_array() - .unwrap_or(&vec![]) - .iter() - .filter_map(|j| serde_json::from_value(j.clone()).ok()) - .collect::>(); - let next = json.get("next").map(|x| x.as_str().unwrap().to_owned()); - Ok((items, next)) - } - pub fn fetch_outbox_page07( + pub fn fetch_outbox_page07( &self, url: &str, ) -> Result<(Vec, Option)> { @@ -544,43 +530,8 @@ impl User { let next = json.get("next").map(|x| x.as_str().unwrap().to_owned()); Ok((items, next)) } - pub fn fetch_outbox(&self) -> Result> { - let mut res = get( - &self.outbox_url[..], - Self::get_sender07(), - CONFIG.proxy().cloned(), - )?; - let text = &res.text()?; - let json: serde_json::Value = serde_json::from_str(text)?; - if let Some(first) = json.get("first") { - let mut items: Vec = Vec::new(); - let mut next = first.as_str().unwrap().to_owned(); - while let Ok((mut page, nxt)) = self.fetch_outbox_page(&next) { - if page.is_empty() { - break; - } - items.append(&mut page); - if let Some(n) = nxt { - if n == next { - break; - } - next = n; - } else { - break; - } - } - Ok(items) - } else { - Ok(json["items"] - .as_array() - .unwrap_or(&vec![]) - .iter() - .filter_map(|j| serde_json::from_value(j.clone()).ok()) - .collect::>()) - } - } - pub fn fetch_outbox07(&self) -> Result> { + pub fn fetch_outbox07(&self) -> Result> { let mut res = get( &self.outbox_url[..], Self::get_sender07(), From 992a482b96d9fc09b10b9af2d16bda9a60435a37 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:26:37 +0900 Subject: [PATCH 186/233] Remove unused ApSignature type --- plume-common/src/activity_pub/mod.rs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index bdfa26ef..b61dcc93 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -293,26 +293,6 @@ pub trait IntoId { impl Link for Id {} -#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] -#[serde(rename_all = "camelCase")] -pub struct ApSignature { - #[activitystreams(concrete(PublicKey), functional)] - pub public_key: Option, -} - -#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] -#[serde(rename_all = "camelCase")] -pub struct PublicKey { - #[activitystreams(concrete(String), functional)] - pub id: Option, - - #[activitystreams(concrete(String), functional)] - pub owner: Option, - - #[activitystreams(concrete(String), functional)] - pub public_key_pem: Option, -} - #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ApSignature07 { From e4180b3b388cb92e444174c39b4fb3dc6bafd254 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:29:44 +0900 Subject: [PATCH 187/233] Rename: ApSignature07 -> ApSignature --- plume-common/src/activity_pub/mod.rs | 28 ++++++++++++++-------------- plume-models/src/blogs.rs | 8 ++++---- plume-models/src/users.rs | 8 ++++---- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index b61dcc93..2c27475f 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -295,26 +295,26 @@ impl Link for Id {} #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct ApSignature07 { - pub public_key: PublicKey07, +pub struct ApSignature { + pub public_key: PublicKey, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct PublicKey07 { +pub struct PublicKey { pub id: IriString, pub owner: IriString, pub public_key_pem: String, } -impl UnparsedExtension for ApSignature07 +impl UnparsedExtension for ApSignature where U: UnparsedMutExt, { type Error = serde_json::Error; fn try_from_unparsed(unparsed_mut: &mut U) -> Result { - Ok(ApSignature07 { + Ok(ApSignature { public_key: unparsed_mut.remove("publicKey")?, }) } @@ -349,8 +349,8 @@ where } } -pub type CustomPerson = Ext1, ApSignature07>; -pub type CustomGroup = Ext2, ApSignature07, SourceProperty>; +pub type CustomPerson = Ext1, ApSignature>; +pub type CustomGroup = Ext2, ApSignature, SourceProperty>; kind!(HashtagType, Hashtag); @@ -584,8 +584,8 @@ mod tests { #[test] fn se_ap_signature() { - let ap_signature = ApSignature07 { - public_key: PublicKey07 { + let ap_signature = ApSignature { + public_key: PublicKey { id: "https://example.com/pubkey".parse().unwrap(), owner: "https://example.com/owner".parse().unwrap(), public_key_pem: "pubKeyPem".into(), @@ -603,7 +603,7 @@ mod tests { #[test] fn de_ap_signature() { - let value: ApSignature07 = from_str( + let value: ApSignature = from_str( r#" { "publicKey": { @@ -615,8 +615,8 @@ mod tests { "#, ) .unwrap(); - let expected = ApSignature07 { - public_key: PublicKey07 { + let expected = ApSignature { + public_key: PublicKey { id: "https://example.com/".parse().unwrap(), owner: "https://example.com/".parse().unwrap(), public_key_pem: "".into(), @@ -630,8 +630,8 @@ mod tests { let actor = ApActor::new("https://example.com/inbox".parse().unwrap(), Person::new()); let person = CustomPerson::new( actor, - ApSignature07 { - public_key: PublicKey07 { + ApSignature { + public_key: PublicKey { id: "https://example.com/pubkey".parse().unwrap(), owner: "https://example.com/owner".parse().unwrap(), public_key_pem: "pubKeyPem".into(), diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 96aec540..94fafba2 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -20,8 +20,8 @@ use openssl::{ }; use plume_common::activity_pub::{ inbox::{AsActor, FromId}, - sign, ActivityStream, ApSignature07, CustomGroup, Id, IntoId, PublicKey07, Source, - SourceProperty, ToAsString, ToAsUri, + sign, ActivityStream, ApSignature, CustomGroup, Id, IntoId, PublicKey, Source, SourceProperty, + ToAsString, ToAsUri, }; use webfinger::*; @@ -209,12 +209,12 @@ impl Blog { blog.set_id(self.ap_url.parse()?); - let pub_key = PublicKey07 { + let pub_key = PublicKey { id: format!("{}#main-key", self.ap_url).parse()?, owner: self.ap_url.parse()?, public_key_pem: self.public_key.clone(), }; - let ap_signature = ApSignature07 { + let ap_signature = ApSignature { public_key: pub_key, }; diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 0677a09a..ef32dfe1 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -28,7 +28,7 @@ use plume_common::{ inbox::{AsActor, AsObject, FromId}, request::get, sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}, - ActivityStream, ApSignature07, CustomPerson, Id, IntoId, PublicKey07, ToAsString, ToAsUri, + ActivityStream, ApSignature, CustomPerson, Id, IntoId, PublicKey, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils, @@ -247,7 +247,7 @@ impl User { let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; let text = &res.text()?; // without this workaround, publicKey is not correctly deserialized - let ap_sign = serde_json::from_str::(text)?; + let ap_sign = serde_json::from_str::(text)?; let person = serde_json::from_str::(text)?; let json = CustomPerson::new( ApActor::new( @@ -795,12 +795,12 @@ impl User { actor.set_endpoints(endpoints); } - let pub_key = PublicKey07 { + let pub_key = PublicKey { id: format!("{}#main-key", self.ap_url).parse()?, owner: ap_url, public_key_pem: self.public_key.clone(), }; - let ap_signature = ApSignature07 { + let ap_signature = ApSignature { public_key: pub_key, }; From f44bca30f48d3f7e24feb4f85b91b909b0cb54df Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:41:05 +0900 Subject: [PATCH 188/233] Use Follow::build_undo07() instead of build_undo() --- plume-models/src/follows.rs | 47 ++++--------------------------------- src/routes/user.rs | 4 ++-- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 9bc2d93f..910942c1 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -2,9 +2,9 @@ use crate::{ ap_url, db_conn::DbConn, instance::Instance, notifications::*, schema::follows, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::activity::{Accept, Follow as FollowAct, Undo}; +use activitypub::activity::{Accept, Follow as FollowAct}; use activitystreams::{ - activity::{Accept as Accept07, ActorAndObjectRef, Follow as FollowAct07, Undo as Undo07}, + activity::{Accept as Accept07, ActorAndObjectRef, Follow as FollowAct07, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -210,23 +210,8 @@ impl Follow { Ok(accept) } - pub fn build_undo(&self, conn: &Connection) -> Result { - let mut undo = Undo::default(); - undo.undo_props - .set_actor_link(User::get(conn, self.follower_id)?.into_id())?; - undo.object_props - .set_id_string(format!("{}/undo", self.ap_url))?; - undo.undo_props - .set_object_link::(self.clone().into_id())?; - undo.object_props - .set_to_link_vec(vec![User::get(conn, self.following_id)?.into_id()])?; - undo.object_props - .set_cc_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - Ok(undo) - } - - pub fn build_undo07(&self, conn: &Connection) -> Result { - let mut undo = Undo07::new( + pub fn build_undo07(&self, conn: &Connection) -> Result { + let mut undo = Undo::new( User::get(conn, self.follower_id)? .ap_url .parse::()?, @@ -296,7 +281,7 @@ impl FromId for Follow { } } -impl AsObject for Follow { +impl AsObject for Follow { type Error = Error; type Output = (); @@ -486,28 +471,6 @@ mod tests { }); } - #[test] - fn build_undo() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (follow, _following, _follower, _users) = prepare_activity(&conn); - let act = follow.build_undo(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/other/", - "cc": ["https://www.w3.org/ns/activitystreams#Public"], - "id": format!("https://plu.me/follows/{}/undo", follow.id), - "object": format!("https://plu.me/follows/{}", follow.id), - "to": ["https://plu.me/@/user/"], - "type": "Undo" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_undo07() { let conn = db(); diff --git a/src/routes/user.rs b/src/routes/user.rs index e89f2d04..2ed62d68 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -105,7 +105,7 @@ pub fn follow( ) -> Result, ErrorPage> { let target = User::find_by_fqn(&conn, &name)?; let message = if let Ok(follow) = follows::Follow::find(&conn, user.id, target.id) { - let delete_act = follow.build_undo(&conn)?; + let delete_act = follow.build_undo07(&conn)?; local_inbox( &conn, serde_json::to_value(&delete_act).map_err(Error::from)?, @@ -114,7 +114,7 @@ pub fn follow( let msg = i18n!(rockets.intl.catalog, "You are no longer following {}."; target.name()); rockets .worker - .execute(move || broadcast(&user, delete_act, vec![target], CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, delete_act, vec![target], CONFIG.proxy().cloned())); msg } else { let f = follows::Follow::insert( From 06d216c7ed82de02510060203e205bc71e1c3418 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:43:47 +0900 Subject: [PATCH 189/233] Remove unused Follow::accept_follow() --- plume-models/src/follows.rs | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 910942c1..dff962e4 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -11,7 +11,7 @@ use activitystreams::{ }; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ - broadcast, broadcast07, + broadcast07, inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, @@ -98,36 +98,6 @@ impl Follow { Ok(()) } - /// from -> The one sending the follow request - /// target -> The target of the request, responding with Accept - pub fn accept_follow + IntoId, T>( - conn: &Connection, - from: &B, - target: &A, - follow: FollowAct, - from_id: i32, - target_id: i32, - ) -> Result { - let res = Follow::insert( - conn, - NewFollow { - follower_id: from_id, - following_id: target_id, - ap_url: follow.object_props.id_string()?, - }, - )?; - res.notify(conn)?; - - let accept = res.build_accept(from, target, follow)?; - broadcast( - &*target, - accept, - vec![from.clone()], - CONFIG.proxy().cloned(), - ); - Ok(res) - } - /// from -> The one sending the follow request /// target -> The target of the request, responding with Accept pub fn accept_follow07 + IntoId, T>( From f8a0dff5267a2977e40328498e186ab5d938065b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:45:22 +0900 Subject: [PATCH 190/233] Remove unused Follow::build_accept() --- plume-models/src/follows.rs | 64 +++---------------------------------- 1 file changed, 4 insertions(+), 60 deletions(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index dff962e4..387858f4 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -2,9 +2,9 @@ use crate::{ ap_url, db_conn::DbConn, instance::Instance, notifications::*, schema::follows, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::activity::{Accept, Follow as FollowAct}; +use activitypub::activity::Follow as FollowAct; use activitystreams::{ - activity::{Accept as Accept07, ActorAndObjectRef, Follow as FollowAct07, Undo}, + activity::{Accept, ActorAndObjectRef, Follow as FollowAct07, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -131,40 +131,13 @@ impl Follow { Ok(res) } - pub fn build_accept + IntoId, T>( - &self, - from: &B, - target: &A, - follow: FollowAct, - ) -> Result { - let mut accept = Accept::default(); - let accept_id = ap_url(&format!( - "{}/follows/{}/accept", - CONFIG.base_url.as_str(), - self.id - )); - accept.object_props.set_id_string(accept_id)?; - accept - .object_props - .set_to_link_vec(vec![from.clone().into_id()])?; - accept - .object_props - .set_cc_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - accept - .accept_props - .set_actor_link::(target.clone().into_id())?; - accept.accept_props.set_object_object(follow)?; - - Ok(accept) - } - pub fn build_accept07 + IntoId, T>( &self, from: &B, target: &A, follow: FollowAct07, - ) -> Result { - let mut accept = Accept07::new( + ) -> Result { + let mut accept = Accept::new( target.clone().into_id().parse::()?, AnyBase::from_extended(follow)?, ); @@ -383,35 +356,6 @@ mod tests { }); } - #[test] - fn build_accept() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (follow, following, follower, _users) = prepare_activity(&conn); - let act = follow.build_accept(&follower, &following, follow.to_activity(&conn)?)?; - - let expected = json!({ - "actor": "https://plu.me/@/user/", - "cc": ["https://www.w3.org/ns/activitystreams#Public"], - "id": format!("https://127.0.0.1:7878/follows/{}/accept", follow.id), - "object": { - "actor": "https://plu.me/@/other/", - "cc": ["https://www.w3.org/ns/activitystreams#Public"], - "id": format!("https://plu.me/follows/{}", follow.id), - "object": "https://plu.me/@/user/", - "to": ["https://plu.me/@/user/"], - "type": "Follow" - }, - "to": ["https://plu.me/@/other/"], - "type": "Accept" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn build_accept07() { let conn = db(); From 595fa05660c564474c9a7ab4b3dce01994d30c7d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:47:46 +0900 Subject: [PATCH 191/233] Use Follow::to_activity07() instead of to_activity() --- plume-models/src/follows.rs | 56 ++++++------------------------------- src/routes/user.rs | 8 ++---- 2 files changed, 12 insertions(+), 52 deletions(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 387858f4..91805f25 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -2,9 +2,8 @@ use crate::{ ap_url, db_conn::DbConn, instance::Instance, notifications::*, schema::follows, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::activity::Follow as FollowAct; use activitystreams::{ - activity::{Accept, ActorAndObjectRef, Follow as FollowAct07, Undo}, + activity::{Accept, ActorAndObjectRef, Follow as FollowAct, Undo}, base::AnyBase, iri_string::types::IriString, prelude::*, @@ -56,27 +55,12 @@ impl Follow { .map_err(Error::from) } - pub fn to_activity(&self, conn: &Connection) -> Result { - let user = User::get(conn, self.follower_id)?; - let target = User::get(conn, self.following_id)?; - - let mut act = FollowAct::default(); - act.follow_props.set_actor_link::(user.into_id())?; - act.follow_props - .set_object_link::(target.clone().into_id())?; - act.object_props.set_id_string(self.ap_url.clone())?; - act.object_props.set_to_link_vec(vec![target.into_id()])?; - act.object_props - .set_cc_link_vec(vec![Id::new(PUBLIC_VISIBILITY.to_string())])?; - Ok(act) - } - - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity07(&self, conn: &Connection) -> Result { let user = User::get(conn, self.follower_id)?; let target = User::get(conn, self.following_id)?; let target_id = target.ap_url.parse::()?; - let mut act = FollowAct07::new(user.ap_url.parse::()?, target_id.clone()); + let mut act = FollowAct::new(user.ap_url.parse::()?, target_id.clone()); act.set_id(self.ap_url.parse::()?); act.set_many_tos(vec![target_id]); act.set_many_ccs(vec![PUBLIC_VISIBILITY.parse::()?]); @@ -104,7 +88,7 @@ impl Follow { conn: &Connection, from: &B, target: &A, - follow: FollowAct07, + follow: FollowAct, from_id: i32, target_id: i32, ) -> Result { @@ -135,7 +119,7 @@ impl Follow { &self, from: &B, target: &A, - follow: FollowAct07, + follow: FollowAct, ) -> Result { let mut accept = Accept::new( target.clone().into_id().parse::()?, @@ -170,7 +154,7 @@ impl Follow { } } -impl AsObject for User { +impl AsObject for User { type Error = Error; type Output = Follow; @@ -178,7 +162,7 @@ impl AsObject for User { // Mastodon (at least) requires the full Follow object when accepting it, // so we rebuilt it here let mut follow = - FollowAct07::new(id.parse::()?, actor.ap_url.parse::()?); + FollowAct::new(id.parse::()?, actor.ap_url.parse::()?); follow.set_id(id.parse::()?); Follow::accept_follow07(conn, &actor, &self, follow, actor.id, self.id) } @@ -186,13 +170,13 @@ impl AsObject for User { impl FromId for Follow { type Error = Error; - type Object = FollowAct07; + type Object = FollowAct; fn from_db07(conn: &DbConn, id: &str) -> Result { Follow::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, follow: FollowAct07) -> Result { + fn from_activity07(conn: &DbConn, follow: FollowAct) -> Result { let actor = User::from_id( conn, follow @@ -312,28 +296,6 @@ mod tests { }) } - #[test] - fn to_activity() { - let conn = db(); - conn.test_transaction::<_, Error, _>(|| { - let (follow, _following, _follower, _users) = prepare_activity(&conn); - let act = follow.to_activity(&conn)?; - - let expected = json!({ - "actor": "https://plu.me/@/other/", - "cc": ["https://www.w3.org/ns/activitystreams#Public"], - "id": format!("https://plu.me/follows/{}", follow.id), - "object": "https://plu.me/@/user/", - "to": ["https://plu.me/@/user/"], - "type": "Follow" - }); - - assert_json_eq!(to_value(act)?, expected); - - Ok(()) - }); - } - #[test] fn to_activity07() { let conn = db(); diff --git a/src/routes/user.rs b/src/routes/user.rs index 2ed62d68..c8327ea7 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -18,9 +18,7 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{ - broadcast, broadcast07, ActivityStream, ApRequest, CustomPerson, Id, -}; +use plume_common::activity_pub::{broadcast07, ActivityStream, ApRequest, CustomPerson, Id}; use plume_common::utils::md_to_html; use plume_models::{ blogs::Blog, @@ -127,11 +125,11 @@ pub fn follow( )?; f.notify(&conn)?; - let act = f.to_activity(&conn)?; + let act = f.to_activity07(&conn)?; let msg = i18n!(rockets.intl.catalog, "You are now following {}."; target.name()); rockets .worker - .execute(move || broadcast(&user, act, vec![target], CONFIG.proxy().cloned())); + .execute(move || broadcast07(&user, act, vec![target], CONFIG.proxy().cloned())); msg }; Ok(Flash::success( From ce425242739e24e838b43ba942a837025c44505d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:50:43 +0900 Subject: [PATCH 192/233] Remote trailng 07 from Note in comments.rs --- plume-models/src/comments.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 499f4a32..0b546d65 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -16,7 +16,7 @@ use activitystreams::{ base::{AnyBase, Base}, iri_string::types::IriString, link::{self, kind::MentionType}, - object::{Note as Note07, Tombstone}, + object::{Note, Tombstone}, prelude::*, primitives::OneOrMany, time::OffsetDateTime, @@ -111,7 +111,7 @@ impl Comment { .unwrap_or(false) } - pub fn to_activity07(&self, conn: &DbConn) -> Result { + pub fn to_activity07(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; let (html, mentions, _hashtags) = utils::md_to_html( self.content.get().as_ref(), @@ -120,7 +120,7 @@ impl Comment { Some(Media::get_media_processor(conn, vec![&author])), ); - let mut note = Note07::new(); + let mut note = Note::new(); let to = vec![PUBLIC_VISIBILITY.parse::()?]; note.set_id( @@ -219,13 +219,13 @@ impl Comment { impl FromId for Comment { type Error = Error; - type Object = Note07; + type Object = Note; fn from_db07(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, note: Note07) -> Result { + fn from_activity07(conn: &DbConn, note: Note) -> Result { let comm = { let previous_url = note .in_reply_to() From 1b32fa1e34ca6368400eb3db95d668c49f42b30e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:54:37 +0900 Subject: [PATCH 193/233] Remove unused Media::from_activity() --- plume-models/src/medias.rs | 96 ++------------------------------------ 1 file changed, 3 insertions(+), 93 deletions(-) diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 6796170c..52c06efb 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -2,12 +2,11 @@ use crate::{ ap_url, db_conn::DbConn, instance::Instance, safe_string::SafeString, schema::medias, users::User, Connection, Error, Result, CONFIG, }; -use activitypub::object::Image; -use activitystreams::{object::Image as Image07, prelude::*}; +use activitystreams::{object::Image, prelude::*}; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; use guid_create::GUID; use plume_common::{ - activity_pub::{inbox::FromId, request, Id, ToAsString, ToAsUri}, + activity_pub::{inbox::FromId, request, ToAsString, ToAsUri}, utils::{escape, MediaProcessor}, }; use std::{ @@ -207,96 +206,7 @@ impl Media { } // TODO: merge with save_remote? - pub fn from_activity(conn: &DbConn, image: &Image) -> Result { - let remote_url = image - .object_props - .url_string() - .or(Err(Error::MissingApProperty))?; - let path = determine_mirror_file_path(&remote_url); - let parent = path.parent().ok_or(Error::InvalidValue)?; - if !parent.is_dir() { - DirBuilder::new().recursive(true).create(parent)?; - } - - let mut dest = fs::File::create(path.clone())?; - // TODO: conditional GET - request::get( - remote_url.as_str(), - User::get_sender07(), - CONFIG.proxy().cloned(), - )? - .copy_to(&mut dest)?; - - Media::find_by_file_path(conn, path.to_str().ok_or(Error::InvalidValue)?) - .and_then(|mut media| { - let mut updated = false; - - let alt_text = image - .object_props - .content_string() - .or(Err(Error::NotFound))?; - let sensitive = image.object_props.summary_string().is_ok(); - let content_warning = image.object_props.summary_string().ok(); - if media.alt_text != alt_text { - media.alt_text = alt_text; - updated = true; - } - if media.is_remote { - media.is_remote = false; - updated = true; - } - if media.remote_url.is_some() { - media.remote_url = None; - updated = true; - } - if media.sensitive != sensitive { - media.sensitive = sensitive; - updated = true; - } - if media.content_warning != content_warning { - media.content_warning = content_warning; - updated = true; - } - if updated { - diesel::update(&media).set(&media).execute(&**conn)?; - } - Ok(media) - }) - .or_else(|_| { - Media::insert( - conn, - NewMedia { - file_path: path.to_str().ok_or(Error::InvalidValue)?.to_string(), - alt_text: image - .object_props - .content_string() - .or(Err(Error::NotFound))?, - is_remote: false, - remote_url: None, - sensitive: image.object_props.summary_string().is_ok(), - content_warning: image.object_props.summary_string().ok(), - owner_id: User::from_id( - conn, - image - .object_props - .attributed_to_link_vec::() - .or(Err(Error::NotFound))? - .into_iter() - .next() - .ok_or(Error::NotFound)? - .as_ref(), - None, - CONFIG.proxy(), - ) - .map_err(|(_, e)| e)? - .id, - }, - ) - }) - } - - // TODO: merge with save_remote? - pub fn from_activity07(conn: &DbConn, image: &Image07) -> Result { + pub fn from_activity07(conn: &DbConn, image: &Image) -> Result { let remote_url = image .url() .and_then(|url| url.to_as_uri()) From fc99d2b7a0efe5efe84daaa770a6731d3d19f734 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 00:57:19 +0900 Subject: [PATCH 194/233] Remove trailing 07 in remote_fetch_actor.rs --- plume-models/src/remote_fetch_actor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index 83d87b85..2d794650 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -6,11 +6,11 @@ use crate::{ ACTOR_SYS, CONFIG, USER_CHAN, }; use activitystreams::{ - activity::{ActorAndObjectRef, Create as Create07}, + activity::{ActorAndObjectRef, Create}, base::AnyBase, object::kind::ArticleType, }; -use plume_common::activity_pub::{inbox::FromId, LicensedArticle as LicensedArticle07}; +use plume_common::activity_pub::{inbox::FromId, LicensedArticle}; use riker::actors::{Actor, ActorFactoryArgs, ActorRefFactory, Context, Sender, Subscribe, Tell}; use std::sync::Arc; use tracing::{error, info, warn}; @@ -68,7 +68,7 @@ impl ActorFactoryArgs for RemoteFetchActor { } fn fetch_and_cache_articles(user: &Arc, conn: &DbConn) { - let create_acts = user.fetch_outbox07::(); + let create_acts = user.fetch_outbox07::(); match create_acts { Ok(create_acts) => { for create_act in create_acts { @@ -77,7 +77,7 @@ fn fetch_and_cache_articles(user: &Arc, conn: &DbConn) { .as_single_base() .and_then(|base| { let any_base = AnyBase::from_base(base.clone()); // FIXME: Don't clone() - any_base.extend::().ok() + any_base.extend::().ok() }) { Some(Some(article)) => { Post::from_activity07(conn, article) From 267fecba66dc6421763bca5cdd8f5fbd15910d9c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:03:54 +0900 Subject: [PATCH 195/233] Remove unsed posts::LicensedArticle --- plume-models/src/posts.rs | 51 ++------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index c6206e65..647d3c02 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -3,7 +3,6 @@ use crate::{ post_authors::*, safe_string::SafeString, schema::posts, tags::*, timeline::*, users::User, Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN, }; -use activitypub::{object::Article, CustomObject}; use activitystreams::{ activity::{Create as Create07, Delete as Delete07, Update as Update07}, base::{AnyBase, Base}, @@ -23,9 +22,8 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, HashtagType, Id, IntoId, Licensed, Licensed07, - LicensedArticle as LicensedArticle07, Source, SourceProperty, ToAsString, ToAsUri, - PUBLIC_VISIBILITY, + Hashtag, HashtagType, Id, IntoId, Licensed07, LicensedArticle as LicensedArticle07, Source, + SourceProperty, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, }; @@ -33,8 +31,6 @@ use riker::actors::{Publish, Tell}; use std::collections::{HashMap, HashSet}; use std::sync::{Arc, Mutex}; -pub type LicensedArticle = CustomObject; - static BLOG_FQN_CACHE: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); #[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)] @@ -1091,49 +1087,6 @@ mod tests { }); } - #[test] - fn licensed_article_serde() { - let mut article = Article::default(); - article.object_props.set_id_string("Yo".into()).unwrap(); - let mut license = Licensed::default(); - license.set_license_string("WTFPL".into()).unwrap(); - let full_article = LicensedArticle::new(article, license); - - let json = serde_json::to_value(full_article).unwrap(); - let article_from_json: LicensedArticle = serde_json::from_value(json).unwrap(); - assert_eq!( - "Yo", - &article_from_json.object.object_props.id_string().unwrap() - ); - assert_eq!( - "WTFPL", - &article_from_json.custom_props.license_string().unwrap() - ); - } - - #[test] - fn licensed_article_deserialization() { - let json = json!({ - "type": "Article", - "id": "https://plu.me/~/Blog/my-article", - "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], - "content": "Hello.", - "name": "My Article", - "summary": "Bye.", - "source": { - "content": "Hello.", - "mediaType": "text/markdown" - }, - "published": "2014-12-12T12:12:12Z", - "to": [plume_common::activity_pub::PUBLIC_VISIBILITY] - }); - let article: LicensedArticle = serde_json::from_value(json).unwrap(); - assert_eq!( - "https://plu.me/~/Blog/my-article", - &article.object.object_props.id_string().unwrap() - ); - } - #[test] fn to_activity07() { let conn = db(); From a24e3c46e6dad26bd4a237c7e4f9a4f471a9a8ef Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:07:52 +0900 Subject: [PATCH 196/233] Remove trailing 07 in posts.rs --- plume-models/src/posts.rs | 61 +++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 647d3c02..1096bcfe 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -4,14 +4,11 @@ use crate::{ Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN, }; use activitystreams::{ - activity::{Create as Create07, Delete as Delete07, Update as Update07}, + activity::{Create, Delete, Update}, base::{AnyBase, Base}, iri_string::types::IriString, - link::{self as link07, kind::MentionType}, - object::{ - kind::ImageType, ApObject, Article as Article07, AsApObject, Image as Image07, - Tombstone as Tombstone07, - }, + link::{self, kind::MentionType}, + object::{kind::ImageType, ApObject, Article, AsApObject, Image, Tombstone}, prelude::*, time::OffsetDateTime, }; @@ -22,8 +19,8 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, HashtagType, Id, IntoId, Licensed07, LicensedArticle as LicensedArticle07, Source, - SourceProperty, ToAsString, ToAsUri, PUBLIC_VISIBILITY, + Hashtag, HashtagType, Id, IntoId, Licensed07, LicensedArticle, Source, SourceProperty, + ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, }; @@ -344,7 +341,7 @@ impl Post { })) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity07(&self, conn: &Connection) -> Result { let cc = self.get_receivers_urls(conn)?; let to = vec![PUBLIC_VISIBILITY.to_string()]; @@ -358,7 +355,7 @@ impl Post { .collect::>(); mentions_json.append(&mut tags_json); - let mut article = ApObject::new(Article07::new()); + let mut article = ApObject::new(Article::new()); article.set_name(self.title.clone()); article.set_id(self.ap_url.parse::()?); @@ -389,7 +386,7 @@ impl Post { if let Some(media_id) = self.cover_id { let media = Media::get(conn, media_id)?; - let mut cover = Image07::new(); + let mut cover = Image::new(); cover.set_url(media.url()?); if media.sensitive { cover.set_summary(media.content_warning.unwrap_or_default()); @@ -415,14 +412,14 @@ impl Post { let license = Licensed07 { license: Some(self.license.clone()), }; - Ok(LicensedArticle07::new(article, license, source)) + Ok(LicensedArticle::new(article, license, source)) } - pub fn create_activity07(&self, conn: &Connection) -> Result { + pub fn create_activity07(&self, conn: &Connection) -> Result { let article = self.to_activity07(conn)?; let to = article.to().ok_or(Error::MissingApProperty)?.clone(); let cc = article.cc().ok_or(Error::MissingApProperty)?.clone(); - let mut act = Create07::new( + let mut act = Create::new( self.get_authors(conn)?[0].ap_url.parse::()?, Base::retract(article)?.into_generic()?, ); @@ -432,11 +429,11 @@ impl Post { Ok(act) } - pub fn update_activity07(&self, conn: &Connection) -> Result { + pub fn update_activity07(&self, conn: &Connection) -> Result { let article = self.to_activity07(conn)?; let to = article.to().ok_or(Error::MissingApProperty)?.clone(); let cc = article.cc().ok_or(Error::MissingApProperty)?.clone(); - let mut act = Update07::new( + let mut act = Update::new( self.get_authors(conn)?[0].ap_url.parse::()?, Base::retract(article)?.into_generic()?, ); @@ -448,11 +445,7 @@ impl Post { Ok(act) } - pub fn update_mentions07( - &self, - conn: &Connection, - mentions: Vec, - ) -> Result<()> { + pub fn update_mentions07(&self, conn: &Connection, mentions: Vec) -> Result<()> { let mentions = mentions .into_iter() .map(|m| { @@ -575,11 +568,11 @@ impl Post { .and_then(|c| c.url().ok()) } - pub fn build_delete07(&self, conn: &Connection) -> Result { - let mut tombstone = Tombstone07::new(); + pub fn build_delete07(&self, conn: &Connection) -> Result { + let mut tombstone = Tombstone::new(); tombstone.set_id(self.ap_url.parse()?); - let mut act = Delete07::new( + let mut act = Delete::new( self.get_authors(conn)?[0] .clone() .into_id() @@ -625,13 +618,13 @@ impl Post { impl FromId for Post { type Error = Error; - type Object = LicensedArticle07; + type Object = LicensedArticle; fn from_db07(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, article: LicensedArticle07) -> Result { + fn from_activity07(conn: &DbConn, article: LicensedArticle) -> Result { let license = article.ext_one.license.unwrap_or_default(); let source = article.ext_two.source.content; let article = article.inner; @@ -663,7 +656,7 @@ impl FromId for Post { let cover = article.icon().and_then(|icon| { icon.iter().next().and_then(|img| { - let image = img.to_owned().extend::().ok()??; + let image = img.to_owned().extend::().ok()??; Media::from_activity07(conn, &image).ok().map(|m| m.id) }) }); @@ -786,7 +779,7 @@ impl FromId for Post { if let Some(tags) = article.tag() { for tag in tags.iter() { tag.clone() - .extend::() // FIXME: Don't clone + .extend::() // FIXME: Don't clone .map(|mention| { mention.map(|m| Mention::from_activity07(conn, &m, post.id, true, true)) }) @@ -814,7 +807,7 @@ impl FromId for Post { } } -impl AsObject for Post { +impl AsObject for Post { type Error = Error; type Output = Self; @@ -824,7 +817,7 @@ impl AsObject for Post { } } -impl AsObject for Post { +impl AsObject for Post { type Error = Error; type Output = (); @@ -854,7 +847,7 @@ pub struct PostUpdate { impl FromId for PostUpdate { type Error = Error; - type Object = LicensedArticle07; + type Object = LicensedArticle; fn from_db07(_: &DbConn, _: &str) -> Result { // Always fail because we always want to deserialize the AP object @@ -892,7 +885,7 @@ impl FromId for PostUpdate { .next() .and_then(|img| { img.clone() - .extend::() + .extend::() .map(|img| img.and_then(|img| Media::from_activity07(conn, &img).ok())) .ok() }) @@ -909,7 +902,7 @@ impl FromId for PostUpdate { } } -impl AsObject for PostUpdate { +impl AsObject for PostUpdate { type Error = Error; type Output = (); @@ -954,7 +947,7 @@ impl AsObject for PostUpdate { let mut tags = vec![]; let mut hashtags = vec![]; for tag in mention_tags { - serde_json::from_value::(tag.clone()) + serde_json::from_value::(tag.clone()) .map(|m| mentions.push(m)) .ok(); From 5c59687cb87df26d55de920ebb0283efc6f94114 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:10:44 +0900 Subject: [PATCH 197/233] Remove unused broadcast() --- plume-common/src/activity_pub/mod.rs | 82 +--------------------------- 1 file changed, 3 insertions(+), 79 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 2c27475f..c1ee1a4f 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,10 +1,10 @@ -use activitypub::{Activity, Link, Object}; +use activitypub::{Link, Object}; use activitystreams::{ actor::{ApActor, Group, Person}, base::{AnyBase, Base, Extends}, iri_string::types::IriString, kind, - markers::{self, Activity as Activity07}, + markers::{self, Activity}, object::{ApObject, Article, Object as Object07}, primitives::{AnyString, OneOrMany}, unparsed::UnparsedMutExt, @@ -119,87 +119,11 @@ impl<'a, 'r> FromRequest<'a, 'r> for ApRequest { .unwrap_or(Outcome::Forward(())) } } -pub fn broadcast(sender: &S, act: A, to: Vec, proxy: Option) -where - S: sign::Signer, - A: Activity, - T: inbox::AsActor, -{ - let boxes = to - .into_iter() - .filter(|u| !u.is_local()) - .map(|u| { - u.get_shared_inbox_url() - .unwrap_or_else(|| u.get_inbox_url()) - }) - .collect::>() - .unique(); - - let mut act = serde_json::to_value(act).expect("activity_pub::broadcast: serialization error"); - act["@context"] = context(); - let signed = act - .sign(sender) - .expect("activity_pub::broadcast: signature error"); - - let mut rt = tokio::runtime::current_thread::Runtime::new() - .expect("Error while initializing tokio runtime for federation"); - for inbox in boxes { - let body = signed.to_string(); - let mut headers = request::headers(); - let url = Url::parse(&inbox); - if url.is_err() { - warn!("Inbox is invalid URL: {:?}", &inbox); - continue; - } - let url = url.unwrap(); - if !url.has_host() { - warn!("Inbox doesn't have host: {:?}", &inbox); - continue; - }; - let host_header_value = HeaderValue::from_str(url.host_str().expect("Unreachable")); - if host_header_value.is_err() { - warn!("Header value is invalid: {:?}", url.host_str()); - continue; - } - headers.insert("Host", host_header_value.unwrap()); - headers.insert("Digest", request::Digest::digest(&body)); - rt.spawn( - if let Some(proxy) = proxy.clone() { - ClientBuilder::new().proxy(proxy) - } else { - ClientBuilder::new() - } - .connect_timeout(std::time::Duration::from_secs(5)) - .build() - .expect("Can't build client") - .post(&inbox) - .headers(headers.clone()) - .header( - "Signature", - request::signature(sender, &headers, ("post", url.path(), url.query())) - .expect("activity_pub::broadcast: request signature error"), - ) - .body(body) - .send() - .and_then(move |r| { - if r.status().is_success() { - debug!("Successfully sent activity to inbox ({})", &inbox); - } else { - warn!("Error while sending to inbox ({:?})", &r) - } - r.into_body().concat2() - }) - .map(move |response| debug!("Response: \"{:?}\"\n", response)) - .map_err(|e| warn!("Error while sending to inbox ({:?})", e)), - ); - } - rt.run().unwrap(); -} pub fn broadcast07(sender: &S, act: A, to: Vec, proxy: Option) where S: sign::Signer, - A: Activity07 + serde::Serialize, + A: Activity + serde::Serialize, T: inbox::AsActor, { let boxes = to From 1dd176dd80b03cd5ec20af5e560f96e63c1fe129 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:12:39 +0900 Subject: [PATCH 198/233] Rename: broadcast07() -> broadcast() --- plume-common/src/activity_pub/mod.rs | 2 +- plume-models/src/follows.rs | 4 ++-- src/api/posts.rs | 4 ++-- src/routes/comments.rs | 6 +++--- src/routes/instance.rs | 4 ++-- src/routes/likes.rs | 6 +++--- src/routes/posts.rs | 10 +++++----- src/routes/reshares.rs | 6 +++--- src/routes/user.rs | 8 ++++---- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index c1ee1a4f..8310ecd1 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -120,7 +120,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for ApRequest { } } -pub fn broadcast07(sender: &S, act: A, to: Vec, proxy: Option) +pub fn broadcast(sender: &S, act: A, to: Vec, proxy: Option) where S: sign::Signer, A: Activity + serde::Serialize, diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 91805f25..7cca5f08 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -10,7 +10,7 @@ use activitystreams::{ }; use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl}; use plume_common::activity_pub::{ - broadcast07, + broadcast, inbox::{AsActor, AsObject, FromId}, sign::Signer, Id, IntoId, PUBLIC_VISIBILITY, @@ -106,7 +106,7 @@ impl Follow { res.notify(conn)?; let accept = res.build_accept07(from, target, follow)?; - broadcast07( + broadcast( &*target, accept, vec![from.clone()], diff --git a/src/api/posts.rs b/src/api/posts.rs index ca76e611..2de03517 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -3,7 +3,7 @@ use rocket_contrib::json::Json; use crate::api::{authorization::*, Api, ApiError}; use plume_api::posts::*; -use plume_common::{activity_pub::broadcast07, utils::md_to_html}; +use plume_common::{activity_pub::broadcast, utils::md_to_html}; use plume_models::{ blogs::Blog, db_conn::DbConn, instance::Instance, medias::Media, mentions::*, post_authors::*, posts::*, safe_string::SafeString, tags::*, timeline::*, users::User, Error, PlumeRocket, @@ -202,7 +202,7 @@ pub fn create( let act = post.create_activity07(&conn)?; let dest = User::one_by_instance(&conn)?; - worker.execute(move || broadcast07(&author, act, dest, CONFIG.proxy().cloned())); + worker.execute(move || broadcast(&author, act, dest, CONFIG.proxy().cloned())); } Timeline::add_to_all_timelines(&conn, &post, Kind::Original)?; diff --git a/src/routes/comments.rs b/src/routes/comments.rs index f7018139..687665e6 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -11,7 +11,7 @@ use std::time::Duration; use crate::routes::errors::ErrorPage; use crate::template_utils::IntoContext; use plume_common::{ - activity_pub::{broadcast07, ActivityStream, ApRequest}, + activity_pub::{broadcast, ActivityStream, ApRequest}, utils, }; use plume_models::{ @@ -88,7 +88,7 @@ pub fn create( let dest = User::one_by_instance(&conn).expect("comments::create: dest error"); let user_clone = user.clone(); rockets.worker.execute(move || { - broadcast07(&user_clone, new_comment, dest, CONFIG.proxy().cloned()) + broadcast(&user_clone, new_comment, dest, CONFIG.proxy().cloned()) }); Flash::success( @@ -158,7 +158,7 @@ pub fn delete( let user_c = user.clone(); rockets.worker.execute(move || { - broadcast07(&user_c, delete_activity, dest, CONFIG.proxy().cloned()) + broadcast(&user_c, delete_activity, dest, CONFIG.proxy().cloned()) }); rockets .worker diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 3864f20c..06cf63cd 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -11,7 +11,7 @@ use validator::{Validate, ValidationErrors}; use crate::inbox; use crate::routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page, RespondOrRedirect}; use crate::template_utils::{IntoContext, Ructe}; -use plume_common::activity_pub::{broadcast07, inbox::FromId}; +use plume_common::activity_pub::{broadcast, inbox::FromId}; use plume_models::{ admin::*, blocklisted_emails::*, @@ -383,7 +383,7 @@ fn ban(id: i32, conn: &Connection, worker: &ScheduledThreadPool) -> Result<(), E .unwrap(); let target = User::one_by_instance(&*conn)?; let delete_act = u.delete_activity07(&*conn)?; - worker.execute(move || broadcast07(&u, delete_act, target, CONFIG.proxy().cloned())); + worker.execute(move || broadcast(&u, delete_act, target, CONFIG.proxy().cloned())); } Ok(()) diff --git a/src/routes/likes.rs b/src/routes/likes.rs index 6ef57225..fc1c2970 100644 --- a/src/routes/likes.rs +++ b/src/routes/likes.rs @@ -3,7 +3,7 @@ use rocket_i18n::I18n; use crate::routes::errors::ErrorPage; use crate::utils::requires_login; -use plume_common::activity_pub::broadcast07; +use plume_common::activity_pub::broadcast; use plume_models::{ blogs::Blog, db_conn::DbConn, inbox::inbox, likes, posts::Post, timeline::*, users::User, Error, PlumeRocket, CONFIG, @@ -30,7 +30,7 @@ pub fn create( let act = like.to_activity07(&*conn)?; rockets .worker - .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } else { let like = likes::Like::find_by_user_on_post(&conn, user.id, post.id)?; let delete_act = like.build_undo07(&conn)?; @@ -42,7 +42,7 @@ pub fn create( let dest = User::one_by_instance(&conn)?; rockets .worker - .execute(move || broadcast07(&user, delete_act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned())); } Ok(Redirect::to(uri!( diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 61c3594c..a27d6f1d 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -16,7 +16,7 @@ use crate::routes::{ use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; use plume_common::activity_pub::{ - broadcast07, ActivityStream, ApRequest, LicensedArticle as LicensedArticle07, + broadcast, ActivityStream, ApRequest, LicensedArticle as LicensedArticle07, }; use plume_common::utils::md_to_html; use plume_models::{ @@ -347,7 +347,7 @@ pub fn update( let dest = User::one_by_instance(&conn).expect("post::update: dest error"); rockets .worker - .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); Timeline::add_to_all_timelines(&conn, &post, Kind::Original).ok(); } else { @@ -357,7 +357,7 @@ pub fn update( let dest = User::one_by_instance(&conn).expect("posts::update: dest error"); rockets .worker - .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } } @@ -546,7 +546,7 @@ pub fn create( .expect("posts::create: activity error"); let dest = User::one_by_instance(&conn).expect("posts::create: dest error"); let worker = &rockets.worker; - worker.execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); + worker.execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); Timeline::add_to_all_timelines(&conn, &post, Kind::Original)?; } @@ -616,7 +616,7 @@ pub fn delete( let user_c = user.clone(); rockets .worker - .execute(move || broadcast07(&user_c, delete_activity, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user_c, delete_activity, dest, CONFIG.proxy().cloned())); rockets .worker .execute_after(Duration::from_secs(10 * 60), move || { diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index 2c14cf9f..e815486b 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -3,7 +3,7 @@ use rocket_i18n::I18n; use crate::routes::errors::ErrorPage; use crate::utils::requires_login; -use plume_common::activity_pub::broadcast07; +use plume_common::activity_pub::broadcast; use plume_models::{ blogs::Blog, db_conn::DbConn, inbox::inbox, posts::Post, reshares::*, timeline::*, users::User, Error, PlumeRocket, CONFIG, @@ -30,7 +30,7 @@ pub fn create( let act = reshare.to_activity07(&conn)?; rockets .worker - .execute(move || broadcast07(&user, act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } else { let reshare = Reshare::find_by_user_on_post(&conn, user.id, post.id)?; let delete_act = reshare.build_undo07(&conn)?; @@ -42,7 +42,7 @@ pub fn create( let dest = User::one_by_instance(&conn)?; rockets .worker - .execute(move || broadcast07(&user, delete_act, dest, CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned())); } Ok(Redirect::to(uri!( diff --git a/src/routes/user.rs b/src/routes/user.rs index c8327ea7..259aaf4d 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -18,7 +18,7 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast07, ActivityStream, ApRequest, CustomPerson, Id}; +use plume_common::activity_pub::{broadcast, ActivityStream, ApRequest, CustomPerson, Id}; use plume_common::utils::md_to_html; use plume_models::{ blogs::Blog, @@ -112,7 +112,7 @@ pub fn follow( let msg = i18n!(rockets.intl.catalog, "You are no longer following {}."; target.name()); rockets .worker - .execute(move || broadcast07(&user, delete_act, vec![target], CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, delete_act, vec![target], CONFIG.proxy().cloned())); msg } else { let f = follows::Follow::insert( @@ -129,7 +129,7 @@ pub fn follow( let msg = i18n!(rockets.intl.catalog, "You are now following {}."; target.name()); rockets .worker - .execute(move || broadcast07(&user, act, vec![target], CONFIG.proxy().cloned())); + .execute(move || broadcast(&user, act, vec![target], CONFIG.proxy().cloned())); msg }; Ok(Flash::success( @@ -389,7 +389,7 @@ pub fn delete( let delete_act = account.delete_activity07(&conn)?; rockets .worker - .execute(move || broadcast07(&account, delete_act, target, CONFIG.proxy().cloned())); + .execute(move || broadcast(&account, delete_act, target, CONFIG.proxy().cloned())); if let Some(cookie) = cookies.get_private(AUTH_COOKIE) { cookies.remove_private(cookie); From e1673787b4a6c8eb5d691fe520ec2a87a53f853c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:14:29 +0900 Subject: [PATCH 199/233] Remove unused Licensed struct --- plume-common/src/activity_pub/mod.rs | 9 --------- plume-common/src/lib.rs | 2 -- 2 files changed, 11 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 8310ecd1..b4d3f153 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -433,15 +433,6 @@ where } } -#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] -#[serde(rename_all = "camelCase")] -pub struct Licensed { - #[activitystreams(concrete(String), functional)] - pub license: Option, -} - -impl Object for Licensed {} - #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Licensed07 { diff --git a/plume-common/src/lib.rs b/plume-common/src/lib.rs index 878923d4..80021762 100644 --- a/plume-common/src/lib.rs +++ b/plume-common/src/lib.rs @@ -1,7 +1,5 @@ #![feature(associated_type_defaults)] -#[macro_use] -extern crate activitystreams_derive; #[macro_use] extern crate shrinkwraprs; #[macro_use] From 6bbadc78b08c327c2349ac78803c56bb1cf87900 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:15:13 +0900 Subject: [PATCH 200/233] Rename: Licensed07 -> Licensed --- plume-common/src/activity_pub/mod.rs | 10 +++++----- plume-models/src/posts.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index b4d3f153..3b421206 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -435,18 +435,18 @@ where #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct Licensed07 { +pub struct Licensed { pub license: Option, } -impl UnparsedExtension for Licensed07 +impl UnparsedExtension for Licensed where U: UnparsedMutExt, { type Error = serde_json::Error; fn try_from_unparsed(unparsed_mut: &mut U) -> Result { - Ok(Licensed07 { + Ok(Licensed { license: unparsed_mut.remove("license")?, }) } @@ -457,7 +457,7 @@ where } } -pub type LicensedArticle = Ext2, Licensed07, SourceProperty>; +pub type LicensedArticle = Ext2, Licensed, SourceProperty>; pub trait ToAsString { fn to_as_string(&self) -> Option; @@ -570,7 +570,7 @@ mod tests { let object = ApObject::new(Article::new()); let licensed_article = LicensedArticle::new( object, - Licensed07 { + Licensed { license: Some("CC-0".into()), }, SourceProperty { diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 1096bcfe..46c48007 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -19,7 +19,7 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, HashtagType, Id, IntoId, Licensed07, LicensedArticle, Source, SourceProperty, + Hashtag, HashtagType, Id, IntoId, Licensed, LicensedArticle, Source, SourceProperty, ToAsString, ToAsUri, PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, @@ -409,7 +409,7 @@ impl Post { .filter_map(|cc| cc.parse::().ok()) .collect::>(), ); - let license = Licensed07 { + let license = Licensed { license: Some(self.license.clone()), }; Ok(LicensedArticle::new(article, license, source)) From ccd3c8a3f29598883b56190d38b35df73c95e379 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:17:27 +0900 Subject: [PATCH 201/233] Don't implement activitypub's Object for Source --- plume-common/src/activity_pub/mod.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 3b421206..f2d1da06 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,11 +1,11 @@ -use activitypub::{Link, Object}; +use activitypub::Link; use activitystreams::{ actor::{ApActor, Group, Person}, base::{AnyBase, Base, Extends}, iri_string::types::IriString, kind, markers::{self, Activity}, - object::{ApObject, Article, Object as Object07}, + object::{ApObject, Article, Object}, primitives::{AnyString, OneOrMany}, unparsed::UnparsedMutExt, }; @@ -287,7 +287,7 @@ pub struct Hashtag { pub name: Option, #[serde(flatten)] - inner: Object07, + inner: Object, } impl Hashtag { @@ -295,18 +295,18 @@ impl Hashtag { Self { href: None, name: None, - inner: Object07::new(), + inner: Object::new(), } } - pub fn extending(mut inner: Object07) -> Result { + pub fn extending(mut inner: Object) -> Result { let href = inner.remove("href")?; let name = inner.remove("name")?; Ok(Self { href, name, inner }) } - pub fn retracting(self) -> Result, serde_json::Error> { + pub fn retracting(self) -> Result, serde_json::Error> { let Self { href, name, @@ -389,7 +389,7 @@ impl Extends for Hashtag { type Error = serde_json::Error; fn extends(base: Base) -> Result { - let inner = Object07::extends(base)?; + let inner = Object::extends(base)?; Self::extending(inner) } @@ -411,8 +411,6 @@ pub struct Source { pub content: String, } -impl Object for Source {} - impl UnparsedExtension for Source where U: UnparsedMutExt, From 9791607793ede97a43cc681936391b34d8da7fe4 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:20:40 +0900 Subject: [PATCH 202/233] Rename: with07() -> with() --- plume-common/src/activity_pub/inbox.rs | 22 +++++++++++----------- plume-models/src/inbox.rs | 24 ++++++++++++------------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 1bc886c3..0b681274 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -197,7 +197,7 @@ where } /// Registers an handler on this Inbox. - pub fn with07(self, proxy: Option<&reqwest::Proxy>) -> Self + pub fn with(self, proxy: Option<&reqwest::Proxy>) -> Self where A: AsActor<&'a C> + FromId, V: activitystreams::markers::Activity + serde::de::DeserializeOwned, @@ -742,7 +742,7 @@ mod tests { fn test_inbox_basic07() { let act = serde_json::to_value(build_create07()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act) - .with07::(None) + .with::(None) .done(); assert!(res.is_ok()); } @@ -751,10 +751,10 @@ mod tests { fn test_inbox_multi_handlers07() { let act = serde_json::to_value(build_create()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act) - .with07::(None) - .with07::(None) - .with07::(None) - .with07::(None) + .with::(None) + .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } @@ -764,8 +764,8 @@ mod tests { let act = serde_json::to_value(build_create07()).unwrap(); // Create is not handled by this inbox let res: Result<(), ()> = Inbox::handle(&(), act) - .with07::(None) - .with07::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_err()); } @@ -818,13 +818,13 @@ mod tests { let act = serde_json::to_value(build_create07()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with07::(None) + .with::(None) .done(); assert!(res.is_err()); let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with07::(None) - .with07::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 9368f5be..86472590 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -51,18 +51,18 @@ impl_into_inbox_result! { pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result { Inbox::handle(conn, act) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) - .with07::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) .done() } From 9a640b3438ef302d83741c6cbe58b54a6e2f4e77 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:22:02 +0900 Subject: [PATCH 203/233] Rename: deref07() -> deref() --- plume-common/src/activity_pub/inbox.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 0b681274..e1a04eeb 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -353,14 +353,14 @@ pub trait FromId: Sized { Ok(x) => Ok(x), _ => match object { Some(o) => Self::from_activity07(ctx, o).map_err(|e| (None, e)), - None => Self::from_activity07(ctx, Self::deref07(id, proxy.cloned())?) + None => Self::from_activity07(ctx, Self::deref(id, proxy.cloned())?) .map_err(|e| (None, e)), }, } } /// Dereferences an ID - fn deref07( + fn deref( id: &str, proxy: Option, ) -> Result, Self::Error)> { From 06d2f68ecd44f89bf6103ec3d57ff5b0bd1b39e9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:22:55 +0900 Subject: [PATCH 204/233] Rename: from_activity07() -> from_activity() --- plume-common/src/activity_pub/inbox.rs | 12 ++++++------ plume-models/src/blogs.rs | 4 ++-- plume-models/src/comments.rs | 4 ++-- plume-models/src/follows.rs | 2 +- plume-models/src/likes.rs | 2 +- plume-models/src/medias.rs | 2 +- plume-models/src/mentions.rs | 2 +- plume-models/src/posts.rs | 18 +++++++++--------- plume-models/src/remote_fetch_actor.rs | 2 +- plume-models/src/reshares.rs | 2 +- plume-models/src/tags.rs | 6 +++--- plume-models/src/users.rs | 6 +++--- src/api/posts.rs | 2 +- src/routes/comments.rs | 2 +- src/routes/posts.rs | 2 +- 15 files changed, 34 insertions(+), 34 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index e1a04eeb..f8ce6a7d 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -352,8 +352,8 @@ pub trait FromId: Sized { match Self::from_db07(ctx, id) { Ok(x) => Ok(x), _ => match object { - Some(o) => Self::from_activity07(ctx, o).map_err(|e| (None, e)), - None => Self::from_activity07(ctx, Self::deref(id, proxy.cloned())?) + Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)), + None => Self::from_activity(ctx, Self::deref(id, proxy.cloned())?) .map_err(|e| (None, e)), }, } @@ -377,7 +377,7 @@ pub trait FromId: Sized { } /// Builds a `Self` from its ActivityPub representation - fn from_activity07(ctx: &C, activity: Self::Object) -> Result; + fn from_activity(ctx: &C, activity: Self::Object) -> Result; /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) fn from_db07(ctx: &C, id: &str) -> Result; @@ -610,7 +610,7 @@ mod tests { Ok(Self) } - fn from_activity07(_: &(), _obj: Person07) -> Result { + fn from_activity(_: &(), _obj: Person07) -> Result { Ok(Self) } @@ -638,7 +638,7 @@ mod tests { Ok(Self) } - fn from_activity07(_: &(), _obj: Note07) -> Result { + fn from_activity(_: &(), _obj: Note07) -> Result { Ok(Self) } @@ -789,7 +789,7 @@ mod tests { Err(()) } - fn from_activity07(_: &(), _obj: Self::Object) -> Result { + fn from_activity(_: &(), _obj: Self::Object) -> Result { Err(()) } diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 94fafba2..0ffc38a9 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -369,7 +369,7 @@ impl FromId for Blog { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, acct: CustomGroup) -> Result { + fn from_activity(conn: &DbConn, acct: CustomGroup) -> Result { let (name, outbox_url, inbox_url) = { let actor = acct.ap_actor_ref(); let name = actor @@ -956,7 +956,7 @@ pub(crate) mod tests { let _: Blog = blogs[0].save_changes(&**conn).unwrap(); let ap_repr = blogs[0].to_activity07(&conn).unwrap(); blogs[0].delete(&conn).unwrap(); - let blog = Blog::from_activity07(&conn, ap_repr).unwrap(); + let blog = Blog::from_activity(&conn, ap_repr).unwrap(); assert_eq!(blog.actor_id, blogs[0].actor_id); assert_eq!(blog.title, blogs[0].title); diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 0b546d65..18f63d6b 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -225,7 +225,7 @@ impl FromId for Comment { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, note: Note) -> Result { + fn from_activity(conn: &DbConn, note: Note) -> Result { let comm = { let previous_url = note .in_reply_to() @@ -299,7 +299,7 @@ impl FromId for Comment { } let m = m.unwrap(); let not_author = m.href().ok_or(Error::MissingApProperty)? != author_url; - let _ = Mention::from_activity07(conn, &m, comm.id, false, not_author); + let _ = Mention::from_activity(conn, &m, comm.id, false, not_author); } } comm diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 7cca5f08..b3d5a07c 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -176,7 +176,7 @@ impl FromId for Follow { Follow::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, follow: FollowAct) -> Result { + fn from_activity(conn: &DbConn, follow: FollowAct) -> Result { let actor = User::from_id( conn, follow diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index e7787e57..8fac8bc3 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -113,7 +113,7 @@ impl FromId for Like { Like::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, act: LikeAct) -> Result { + fn from_activity(conn: &DbConn, act: LikeAct) -> Result { let res = Like::insert( conn, NewLike { diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 52c06efb..da59044b 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -206,7 +206,7 @@ impl Media { } // TODO: merge with save_remote? - pub fn from_activity07(conn: &DbConn, image: &Image) -> Result { + pub fn from_activity(conn: &DbConn, image: &Image) -> Result { let remote_url = image .url() .and_then(|url| url.to_as_uri()) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 0e9a8ba0..56697dde 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -76,7 +76,7 @@ impl Mention { Ok(mention) } - pub fn from_activity07( + pub fn from_activity( conn: &Connection, ment: &link::Mention, inside: i32, diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 46c48007..8217e6b8 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -466,7 +466,7 @@ impl Post { .collect::>(); for (m, id) in &mentions { if !old_user_mentioned.contains(id) { - Mention::from_activity07(&*conn, m, self.id, true, true)?; + Mention::from_activity(&*conn, m, self.id, true, true)?; } } @@ -508,7 +508,7 @@ impl Post { .map(|n| old_tags_name.contains(n.as_str())) .unwrap_or(true) { - Tag::from_activity07(conn, &t, self.id, false)?; + Tag::from_activity(conn, &t, self.id, false)?; } } @@ -545,7 +545,7 @@ impl Post { .map(|n| old_tags_name.contains(n.as_str())) .unwrap_or(true) { - Tag::from_activity07(conn, &t, self.id, true)?; + Tag::from_activity(conn, &t, self.id, true)?; } } @@ -624,7 +624,7 @@ impl FromId for Post { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, article: LicensedArticle) -> Result { + fn from_activity(conn: &DbConn, article: LicensedArticle) -> Result { let license = article.ext_one.license.unwrap_or_default(); let source = article.ext_two.source.content; let article = article.inner; @@ -657,7 +657,7 @@ impl FromId for Post { let cover = article.icon().and_then(|icon| { icon.iter().next().and_then(|img| { let image = img.to_owned().extend::().ok()??; - Media::from_activity07(conn, &image).ok().map(|m| m.id) + Media::from_activity(conn, &image).ok().map(|m| m.id) }) }); @@ -781,7 +781,7 @@ impl FromId for Post { tag.clone() .extend::() // FIXME: Don't clone .map(|mention| { - mention.map(|m| Mention::from_activity07(conn, &m, post.id, true, true)) + mention.map(|m| Mention::from_activity(conn, &m, post.id, true, true)) }) .ok(); @@ -790,7 +790,7 @@ impl FromId for Post { .map(|hashtag| { hashtag.and_then(|t| { let tag_name = t.name.clone()?.as_str().to_string(); - Tag::from_activity07(conn, &t, post.id, hashtags.remove(&tag_name)).ok() + Tag::from_activity(conn, &t, post.id, hashtags.remove(&tag_name)).ok() }) }) .ok(); @@ -854,7 +854,7 @@ impl FromId for PostUpdate { Err(Error::NotFound) } - fn from_activity07(conn: &DbConn, updated: Self::Object) -> Result { + fn from_activity(conn: &DbConn, updated: Self::Object) -> Result { let mut post_update = PostUpdate { ap_url: updated .ap_object_ref() @@ -886,7 +886,7 @@ impl FromId for PostUpdate { .and_then(|img| { img.clone() .extend::() - .map(|img| img.and_then(|img| Media::from_activity07(conn, &img).ok())) + .map(|img| img.and_then(|img| Media::from_activity(conn, &img).ok())) .ok() }) .and_then(|m| m.map(|m| m.id)) diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index 2d794650..228671e3 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -80,7 +80,7 @@ fn fetch_and_cache_articles(user: &Arc, conn: &DbConn) { any_base.extend::().ok() }) { Some(Some(article)) => { - Post::from_activity07(conn, article) + Post::from_activity(conn, article) .expect("Article from remote user couldn't be saved"); info!("Fetched article from remote user"); } diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 3c55658e..72628a0e 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -142,7 +142,7 @@ impl FromId for Reshare { Reshare::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, act: Announce) -> Result { + fn from_activity(conn: &DbConn, act: Announce) -> Result { let res = Reshare::insert( conn, NewReshare { diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index eb24f0c0..2bf35edc 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -39,7 +39,7 @@ impl Tag { Ok(ht) } - pub fn from_activity07( + pub fn from_activity( conn: &Connection, tag: &Hashtag, post: i32, @@ -86,7 +86,7 @@ mod tests { use serde_json::to_value; #[test] - fn from_activity07() { + fn from_activity() { let conn = &db(); conn.test_transaction::<_, Error, _>(|| { let (posts, _users, _blogs) = fill_database(conn); @@ -94,7 +94,7 @@ mod tests { let mut ht = Hashtag::new(); ht.set_href(ap_url(&format!("https://plu.me/tag/a_tag")).parse::()?); ht.set_name("a_tag".to_string()); - let tag = Tag::from_activity07(conn, &ht, post_id, true)?; + let tag = Tag::from_activity(conn, &ht, post_id, true)?; assert_eq!(&tag.tag, "a_tag"); assert!(tag.is_hashtag); diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index ef32dfe1..b65b839a 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -264,7 +264,7 @@ impl User { } pub fn fetch_from_url(conn: &DbConn, url: &str) -> Result { - User::fetch(url).and_then(|json| User::from_activity07(conn, json)) + User::fetch(url).and_then(|json| User::from_activity(conn, json)) } pub fn refetch(&self, conn: &Connection) -> Result<()> { @@ -952,7 +952,7 @@ impl FromId for User { Self::find_by_ap_url(conn, id) } - fn from_activity07(conn: &DbConn, acct: CustomPerson) -> Result { + fn from_activity(conn: &DbConn, acct: CustomPerson) -> Result { let actor = acct.ap_actor_ref(); let username = actor .preferred_username() @@ -1428,7 +1428,7 @@ pub(crate) mod tests { let ap_repr = users[0].to_activity07(&conn).unwrap(); users[0].delete(&conn).unwrap(); - let user = User::from_activity07(&conn, ap_repr).unwrap(); + let user = User::from_activity(&conn, ap_repr).unwrap(); assert_eq!(user.username, users[0].username); assert_eq!(user.display_name, users[0].display_name); diff --git a/src/api/posts.rs b/src/api/posts.rs index 2de03517..d08d8d6a 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -191,7 +191,7 @@ pub fn create( if post.published { for m in mentions.into_iter() { - Mention::from_activity07( + Mention::from_activity( &conn, &Mention::build_activity07(&conn, &m)?, post.id, diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 687665e6..5fd2cbcc 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -71,7 +71,7 @@ pub fn create( // save mentions for ment in mentions { - Mention::from_activity07( + Mention::from_activity( &conn, &Mention::build_activity07(&conn, &ment) .expect("comments::create: build mention error"), diff --git a/src/routes/posts.rs b/src/routes/posts.rs index a27d6f1d..39209824 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -530,7 +530,7 @@ pub fn create( if post.published { for m in mentions { - Mention::from_activity07( + Mention::from_activity( &conn, &Mention::build_activity07(&conn, &m) .expect("post::create: mention build error"), From 7dd56a71e35af514eb2ea318b9afa344166842b9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:23:37 +0900 Subject: [PATCH 205/233] Rename: from_db07() -> from_db() --- plume-common/src/activity_pub/inbox.rs | 10 +++++----- plume-models/src/blogs.rs | 2 +- plume-models/src/comments.rs | 2 +- plume-models/src/follows.rs | 2 +- plume-models/src/likes.rs | 2 +- plume-models/src/posts.rs | 6 +++--- plume-models/src/reshares.rs | 2 +- plume-models/src/users.rs | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index f8ce6a7d..daf3e949 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -349,7 +349,7 @@ pub trait FromId: Sized { object: Option, proxy: Option<&reqwest::Proxy>, ) -> Result, Self::Error)> { - match Self::from_db07(ctx, id) { + match Self::from_db(ctx, id) { Ok(x) => Ok(x), _ => match object { Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)), @@ -380,7 +380,7 @@ pub trait FromId: Sized { fn from_activity(ctx: &C, activity: Self::Object) -> Result; /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) - fn from_db07(ctx: &C, id: &str) -> Result; + fn from_db(ctx: &C, id: &str) -> Result; fn get_sender07() -> &'static dyn Signer; } @@ -606,7 +606,7 @@ mod tests { type Error = (); type Object = Person07; - fn from_db07(_: &(), _id: &str) -> Result { + fn from_db(_: &(), _id: &str) -> Result { Ok(Self) } @@ -634,7 +634,7 @@ mod tests { type Error = (); type Object = Note07; - fn from_db07(_: &(), _id: &str) -> Result { + fn from_db(_: &(), _id: &str) -> Result { Ok(Self) } @@ -785,7 +785,7 @@ mod tests { type Error = (); type Object = Person07; - fn from_db07(_: &(), _id: &str) -> Result { + fn from_db(_: &(), _id: &str) -> Result { Err(()) } diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 0ffc38a9..54ab27b7 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -365,7 +365,7 @@ impl FromId for Blog { type Error = Error; type Object = CustomGroup; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 18f63d6b..aa3f61bd 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -221,7 +221,7 @@ impl FromId for Comment { type Error = Error; type Object = Note; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index b3d5a07c..c8e7e691 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -172,7 +172,7 @@ impl FromId for Follow { type Error = Error; type Object = FollowAct; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Follow::find_by_ap_url(conn, id) } diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 8fac8bc3..fc0b016c 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -109,7 +109,7 @@ impl FromId for Like { type Error = Error; type Object = LikeAct; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Like::find_by_ap_url(conn, id) } diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 8217e6b8..d305578e 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -620,7 +620,7 @@ impl FromId for Post { type Error = Error; type Object = LicensedArticle; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } @@ -674,7 +674,7 @@ impl FromId for Post { .url() .and_then(|url| url.to_as_uri().or(id)) .ok_or(Error::MissingApProperty)?; - let post = Post::from_db07(conn, &ap_url) + let post = Post::from_db(conn, &ap_url) .and_then(|mut post| { let mut updated = false; @@ -849,7 +849,7 @@ impl FromId for PostUpdate { type Error = Error; type Object = LicensedArticle; - fn from_db07(_: &DbConn, _: &str) -> Result { + fn from_db(_: &DbConn, _: &str) -> Result { // Always fail because we always want to deserialize the AP object Err(Error::NotFound) } diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 72628a0e..d2c943bd 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -138,7 +138,7 @@ impl FromId for Reshare { type Error = Error; type Object = Announce; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Reshare::find_by_ap_url(conn, id) } diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index b65b839a..4015f29a 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -948,7 +948,7 @@ impl FromId for User { type Error = Error; type Object = CustomPerson; - fn from_db07(conn: &DbConn, id: &str) -> Result { + fn from_db(conn: &DbConn, id: &str) -> Result { Self::find_by_ap_url(conn, id) } From 15134eed6022f87d2d366d561d2c7d1d9c9796fa Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:24:22 +0900 Subject: [PATCH 206/233] Rename: get_sender07() -> get_sender() --- plume-common/src/activity_pub/inbox.rs | 10 +++++----- plume-models/src/blogs.rs | 2 +- plume-models/src/comments.rs | 2 +- plume-models/src/follows.rs | 2 +- plume-models/src/likes.rs | 2 +- plume-models/src/medias.rs | 2 +- plume-models/src/posts.rs | 4 ++-- plume-models/src/reshares.rs | 2 +- plume-models/src/users.rs | 10 +++++----- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index daf3e949..2a6d53fb 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -364,7 +364,7 @@ pub trait FromId: Sized { id: &str, proxy: Option, ) -> Result, Self::Error)> { - request::get(id, Self::get_sender07(), proxy) + request::get(id, Self::get_sender(), proxy) .map_err(|_| (None, InboxError::DerefError)) .and_then(|mut r| { let json: serde_json::Value = r @@ -382,7 +382,7 @@ pub trait FromId: Sized { /// Tries to find a `Self` with a given ID (`id`), using `ctx` (a database) fn from_db(ctx: &C, id: &str) -> Result; - fn get_sender07() -> &'static dyn Signer; + fn get_sender() -> &'static dyn Signer; } /// Should be implemented by anything representing an ActivityPub actor. @@ -614,7 +614,7 @@ mod tests { Ok(Self) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { &*MY_SIGNER } } @@ -642,7 +642,7 @@ mod tests { Ok(Self) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { &*MY_SIGNER } } @@ -793,7 +793,7 @@ mod tests { Err(()) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { &*MY_SIGNER } } diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 54ab27b7..a08ac0f5 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -475,7 +475,7 @@ impl FromId for Blog { Blog::insert(conn, new_blog) } - fn get_sender07() -> &'static dyn sign::Signer { + fn get_sender() -> &'static dyn sign::Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index aa3f61bd..f19f4691 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -349,7 +349,7 @@ impl FromId for Comment { Ok(comm) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index c8e7e691..bf1268c2 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -203,7 +203,7 @@ impl FromId for Follow { Follow::accept_follow07(conn, &actor, &target, follow, actor.id, target.id) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index fc0b016c..74d9ee83 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -149,7 +149,7 @@ impl FromId for Like { Ok(res) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index da59044b..0db6b2ab 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -221,7 +221,7 @@ impl Media { // TODO: conditional GET request::get( remote_url.as_str(), - User::get_sender07(), + User::get_sender(), CONFIG.proxy().cloned(), )? .copy_to(&mut dest)?; diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index d305578e..fd797cd9 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -802,7 +802,7 @@ impl FromId for Post { Ok(post) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to get local instance user") } } @@ -897,7 +897,7 @@ impl FromId for PostUpdate { Ok(post_update) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index d2c943bd..f169aa66 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -178,7 +178,7 @@ impl FromId for Reshare { Ok(res) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 4015f29a..d2e3ab1b 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -244,7 +244,7 @@ impl User { } fn fetch(url: &str) -> Result { - let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; + let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; let text = &res.text()?; // without this workaround, publicKey is not correctly deserialized let ap_sign = serde_json::from_str::(text)?; @@ -517,7 +517,7 @@ impl User { &self, url: &str, ) -> Result<(Vec, Option)> { - let mut res = get(url, Self::get_sender07(), CONFIG.proxy().cloned())?; + let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; let text = &res.text()?; let json: serde_json::Value = serde_json::from_str(text)?; let items = json["items"] @@ -534,7 +534,7 @@ impl User { pub fn fetch_outbox07(&self) -> Result> { let mut res = get( &self.outbox_url[..], - Self::get_sender07(), + Self::get_sender(), CONFIG.proxy().cloned(), )?; let text = &res.text()?; @@ -570,7 +570,7 @@ impl User { pub fn fetch_followers_ids(&self) -> Result> { let mut res = get( &self.followers_endpoint[..], - Self::get_sender07(), + Self::get_sender(), CONFIG.proxy().cloned(), )?; let text = &res.text()?; @@ -1044,7 +1044,7 @@ impl FromId for User { Ok(user) } - fn get_sender07() -> &'static dyn Signer { + fn get_sender() -> &'static dyn Signer { Instance::get_local_instance_user().expect("Failed to local instance user") } } From df005a28f8db1e38a710fdddf3ba3887375bb22f Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:26:15 +0900 Subject: [PATCH 207/233] Rename: activity07() -> activity() --- plume-common/src/activity_pub/inbox.rs | 34 ++++++-------------------- plume-models/src/blogs.rs | 8 +++--- plume-models/src/comments.rs | 20 +++++++-------- plume-models/src/follows.rs | 12 ++++----- plume-models/src/likes.rs | 12 ++++----- plume-models/src/mentions.rs | 12 ++++----- plume-models/src/posts.rs | 34 +++++++++++++------------- plume-models/src/reshares.rs | 12 ++++----- plume-models/src/tags.rs | 12 ++++----- plume-models/src/timeline/mod.rs | 5 +--- plume-models/src/users.rs | 20 +++++++-------- src/api/posts.rs | 4 +-- src/routes/blogs.rs | 2 +- src/routes/comments.rs | 6 ++--- src/routes/instance.rs | 2 +- src/routes/likes.rs | 2 +- src/routes/posts.rs | 17 ++++++------- src/routes/reshares.rs | 2 +- src/routes/user.rs | 6 ++--- 19 files changed, 99 insertions(+), 123 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 2a6d53fb..fd89fa40 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -260,7 +260,7 @@ where }; // Handle the activity - match obj.activity07(ctx, actor, act_id) { + match obj.activity(ctx, actor, act_id) { Ok(res) => Self::Handled(res.into()), Err(e) => Self::Failed(e), } @@ -540,7 +540,7 @@ where /// - `ctx`: the context passed to `Inbox::handle` /// - `actor`: the actor who did this activity /// - `id`: the ID of this activity - fn activity07(self, ctx: C, actor: A, id: &str) -> Result; + fn activity(self, ctx: C, actor: A, id: &str) -> Result; } #[cfg(test)] @@ -650,12 +650,7 @@ mod tests { type Error = (); type Output = (); - fn activity07( - self, - _: &(), - _actor: MyActor, - _id: &str, - ) -> Result { + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { println!("MyActor is creating a Note"); Ok(()) } @@ -665,12 +660,7 @@ mod tests { type Error = (); type Output = (); - fn activity07( - self, - _: &(), - _actor: MyActor, - _id: &str, - ) -> Result { + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { println!("MyActor is liking a Note"); Ok(()) } @@ -680,12 +670,7 @@ mod tests { type Error = (); type Output = (); - fn activity07( - self, - _: &(), - _actor: MyActor, - _id: &str, - ) -> Result { + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { println!("MyActor is deleting a Note"); Ok(()) } @@ -695,12 +680,7 @@ mod tests { type Error = (); type Output = (); - fn activity07( - self, - _: &(), - _actor: MyActor, - _id: &str, - ) -> Result { + fn activity(self, _: &(), _actor: MyActor, _id: &str) -> Result { println!("MyActor is announcing a Note"); Ok(()) } @@ -802,7 +782,7 @@ mod tests { type Error = (); type Output = (); - fn activity07( + fn activity( self, _: &(), _actor: FailingActor, diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index a08ac0f5..4deb71c6 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -160,7 +160,7 @@ impl Blog { }) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let mut blog = ApActor::new(self.inbox_url.parse()?, Group::new()); blog.set_preferred_username(self.actor_id.clone()); blog.set_name(self.title.clone()); @@ -954,7 +954,7 @@ pub(crate) mod tests { .id, ); let _: Blog = blogs[0].save_changes(&**conn).unwrap(); - let ap_repr = blogs[0].to_activity07(&conn).unwrap(); + let ap_repr = blogs[0].to_activity(&conn).unwrap(); blogs[0].delete(&conn).unwrap(); let blog = Blog::from_activity(&conn, ap_repr).unwrap(); @@ -976,12 +976,12 @@ pub(crate) mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = &db(); conn.test_transaction::<_, Error, _>(|| { let (_users, blogs) = fill_database(&conn); let blog = &blogs[0]; - let act = blog.to_activity07(conn)?; + let act = blog.to_activity(conn)?; let expected = json!({ "icon": { diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index f19f4691..03944b3b 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -111,7 +111,7 @@ impl Comment { .unwrap_or(false) } - pub fn to_activity07(&self, conn: &DbConn) -> Result { + pub fn to_activity(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; let (html, mentions, _hashtags) = utils::md_to_html( self.content.get().as_ref(), @@ -142,17 +142,17 @@ impl Comment { note.set_attributed_to(author.into_id().parse::()?); note.set_many_tos(to); note.set_many_tags(mentions.into_iter().filter_map(|m| { - Mention::build_activity07(conn, &m) + Mention::build_activity(conn, &m) .map(|mention| mention.into_any_base().expect("Can convert")) .ok() })); Ok(note) } - pub fn create_activity07(&self, conn: &DbConn) -> Result { + pub fn create_activity(&self, conn: &DbConn) -> Result { let author = User::get(conn, self.author_id)?; - let note = self.to_activity07(conn)?; + let note = self.to_activity(conn)?; let note_clone = note.clone(); let mut act = Create::new( @@ -358,7 +358,7 @@ impl AsObject for Comment { type Error = Error; type Output = Self; - fn activity07(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { + fn activity(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { // The actual creation takes place in the FromId impl Ok(self) } @@ -368,7 +368,7 @@ impl AsObject for Comment { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { if self.author_id != actor.id { return Err(Error::Unauthorized); } @@ -458,7 +458,7 @@ mod tests { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let (original_comm, posts, users, _blogs) = prepare_activity(&conn); - let act = original_comm.create_activity07(&conn).unwrap(); + let act = original_comm.create_activity(&conn).unwrap(); assert_json_eq!(to_value(&act).unwrap(), json!({ "actor": "https://plu.me/@/admin/", @@ -500,7 +500,7 @@ mod tests { }, ) .unwrap(); - let reply_act = reply.create_activity07(&conn).unwrap(); + let reply_act = reply.create_activity(&conn).unwrap(); assert_json_eq!(to_value(&reply_act).unwrap(), json!({ "actor": "https://plu.me/@/user/", @@ -544,11 +544,11 @@ mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (comment, _posts, _users, _blogs) = prepare_activity(&conn); - let act = comment.to_activity07(&conn)?; + let act = comment.to_activity(&conn)?; let expected = json!({ "attributedTo": "https://plu.me/@/admin/", diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index bf1268c2..c8ebe843 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -55,7 +55,7 @@ impl Follow { .map_err(Error::from) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let user = User::get(conn, self.follower_id)?; let target = User::get(conn, self.following_id)?; let target_id = target.ap_url.parse::()?; @@ -158,7 +158,7 @@ impl AsObject for User { type Error = Error; type Output = Follow; - fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { + fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { // Mastodon (at least) requires the full Follow object when accepting it, // so we rebuilt it here let mut follow = @@ -212,7 +212,7 @@ impl AsObject for Follow { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { let conn = conn; if self.follower_id == actor.id { diesel::delete(&self).execute(&**conn)?; @@ -297,11 +297,11 @@ mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (follow, _following, _follower, _users) = prepare_activity(&conn); - let act = follow.to_activity07(&conn)?; + let act = follow.to_activity(&conn)?; let expected = json!({ "actor": "https://plu.me/@/other/", @@ -323,7 +323,7 @@ mod tests { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (follow, following, follower, _users) = prepare_activity(&conn); - let act = follow.build_accept07(&follower, &following, follow.to_activity07(&conn)?)?; + let act = follow.build_accept07(&follower, &following, follow.to_activity(&conn)?)?; let expected = json!({ "actor": "https://plu.me/@/user/", diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 74d9ee83..b6ff9421 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -39,7 +39,7 @@ impl Like { find_by!(likes, find_by_ap_url, ap_url as &str); find_by!(likes, find_by_user_on_post, user_id as i32, post_id as i32); - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let mut act = LikeAct::new( User::get(conn, self.user_id)?.ap_url.parse::()?, Post::get(conn, self.post_id)?.ap_url.parse::()?, @@ -73,7 +73,7 @@ impl Like { pub fn build_undo07(&self, conn: &Connection) -> Result { let mut act = Undo::new( User::get(conn, self.user_id)?.ap_url.parse::()?, - AnyBase::from_extended(self.to_activity07(conn)?)?, + AnyBase::from_extended(self.to_activity(conn)?)?, ); act.set_id(format!("{}#delete", self.ap_url).parse::()?); act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); @@ -89,7 +89,7 @@ impl AsObject for Post { type Error = Error; type Output = Like; - fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { + fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { let res = Like::insert( conn, NewLike { @@ -158,7 +158,7 @@ impl AsObject for Like { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { if actor.id == self.user_id { diesel::delete(&self).execute(&**conn)?; @@ -193,14 +193,14 @@ mod tests { use serde_json::{json, to_value}; #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (posts, _users, _blogs) = fill_database(&conn); let post = &posts[0]; let user = &post.get_authors(&conn)?[0]; let like = Like::insert(&*conn, NewLike::new(post, user))?; - let act = like.to_activity07(&conn).unwrap(); + let act = like.to_activity(&conn).unwrap(); let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 56697dde..dddb4250 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -60,7 +60,7 @@ impl Mention { } } - pub fn build_activity07(conn: &DbConn, ment: &str) -> Result { + pub fn build_activity(conn: &DbConn, ment: &str) -> Result { let user = User::find_by_fqn(conn, ment)?; let mut mention = link::Mention::new(); mention.set_href(user.ap_url.parse::()?); @@ -68,7 +68,7 @@ impl Mention { Ok(mention) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let user = self.get_mentioned(conn)?; let mut mention = link::Mention::new(); mention.set_href(user.ap_url.parse::()?); @@ -157,13 +157,13 @@ mod tests { use serde_json::{json, to_value}; #[test] - fn build_activity07() { + fn build_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (_posts, users, _blogs) = fill_database(&conn); let user = &users[0]; let name = &user.username; - let act = Mention::build_activity07(&conn, name)?; + let act = Mention::build_activity(&conn, name)?; let expected = json!({ "href": "https://plu.me/@/admin/", @@ -178,7 +178,7 @@ mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (posts, users, _blogs) = fill_database(&conn); @@ -192,7 +192,7 @@ mod tests { comment_id: None, }, )?; - let act = mention.to_activity07(&conn)?; + let act = mention.to_activity(&conn)?; let expected = json!({ "href": "https://plu.me/@/admin/", diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index fd797cd9..dfa15a72 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -341,17 +341,17 @@ impl Post { })) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let cc = self.get_receivers_urls(conn)?; let to = vec![PUBLIC_VISIBILITY.to_string()]; let mut mentions_json = Mention::list_for_post(conn, self.id)? .into_iter() - .map(|m| json!(m.to_activity07(conn).ok())) + .map(|m| json!(m.to_activity(conn).ok())) .collect::>(); let mut tags_json = Tag::for_post(conn, self.id)? .into_iter() - .map(|t| json!(t.to_activity07().ok())) + .map(|t| json!(t.to_activity().ok())) .collect::>(); mentions_json.append(&mut tags_json); @@ -415,8 +415,8 @@ impl Post { Ok(LicensedArticle::new(article, license, source)) } - pub fn create_activity07(&self, conn: &Connection) -> Result { - let article = self.to_activity07(conn)?; + pub fn create_activity(&self, conn: &Connection) -> Result { + let article = self.to_activity(conn)?; let to = article.to().ok_or(Error::MissingApProperty)?.clone(); let cc = article.cc().ok_or(Error::MissingApProperty)?.clone(); let mut act = Create::new( @@ -429,8 +429,8 @@ impl Post { Ok(act) } - pub fn update_activity07(&self, conn: &Connection) -> Result { - let article = self.to_activity07(conn)?; + pub fn update_activity(&self, conn: &Connection) -> Result { + let article = self.to_activity(conn)?; let to = article.to().ok_or(Error::MissingApProperty)?.clone(); let cc = article.cc().ok_or(Error::MissingApProperty)?.clone(); let mut act = Update::new( @@ -811,7 +811,7 @@ impl AsObject for Post { type Error = Error; type Output = Self; - fn activity07(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { + fn activity(self, _conn: &DbConn, _actor: User, _id: &str) -> Result { // TODO: check that _actor is actually one of the author? Ok(self) } @@ -821,7 +821,7 @@ impl AsObject for Post { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result { let can_delete = self .get_authors(conn)? .into_iter() @@ -906,7 +906,7 @@ impl AsObject for PostUpdate { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { let mut post = Post::from_id(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?; @@ -1062,7 +1062,7 @@ mod tests { }, ) .unwrap(); - let create = post.create_activity07(&conn).unwrap(); + let create = post.create_activity(&conn).unwrap(); post.delete(&conn).unwrap(); match inbox(&conn, serde_json::to_value(create).unwrap()).unwrap() { @@ -1081,11 +1081,11 @@ mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.to_activity07(&conn)?; + let act = post.to_activity(&conn)?; let expected = json!({ "attributedTo": ["https://plu.me/@/admin/", "https://plu.me/~/BlogName/"], @@ -1119,11 +1119,11 @@ mod tests { } #[test] - fn create_activity07() { + fn create_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.create_activity07(&conn)?; + let act = post.create_activity(&conn)?; let expected = json!({ "actor": "https://plu.me/@/admin/", @@ -1164,11 +1164,11 @@ mod tests { } #[test] - fn update_activity07() { + fn update_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.update_activity07(&conn)?; + let act = post.update_activity(&conn)?; let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index f169aa66..e0d973ab 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -65,7 +65,7 @@ impl Reshare { User::get(conn, self.user_id) } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let mut act = Announce::new( User::get(conn, self.user_id)?.ap_url.parse::()?, Post::get(conn, self.post_id)?.ap_url.parse::()?, @@ -100,7 +100,7 @@ impl Reshare { pub fn build_undo07(&self, conn: &Connection) -> Result { let mut act = Undo::new( User::get(conn, self.user_id)?.ap_url.parse::()?, - AnyBase::from_extended(self.to_activity07(conn)?)?, + AnyBase::from_extended(self.to_activity(conn)?)?, ); act.set_id(format!("{}#delete", self.ap_url).parse::()?); act.set_many_tos(vec![PUBLIC_VISIBILITY.parse::()?]); @@ -117,7 +117,7 @@ impl AsObject for Post { type Error = Error; type Output = Reshare; - fn activity07(self, conn: &DbConn, actor: User, id: &str) -> Result { + fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { let conn = conn; let reshare = Reshare::insert( conn, @@ -187,7 +187,7 @@ impl AsObject for Reshare { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { if actor.id == self.user_id { diesel::delete(&self).execute(&**conn)?; @@ -223,14 +223,14 @@ mod test { use serde_json::{json, to_value}; #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (posts, _users, _blogs) = fill_database(&conn); let post = &posts[0]; let user = &post.get_authors(&conn)?[0]; let reshare = Reshare::insert(&*conn, NewReshare::new(post, user))?; - let act = reshare.to_activity07(&conn).unwrap(); + let act = reshare.to_activity(&conn).unwrap(); let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index 2bf35edc..681de5e1 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -25,7 +25,7 @@ impl Tag { find_by!(tags, find_by_name, tag as &str); list_by!(tags, for_post, post_id as i32); - pub fn to_activity07(&self) -> Result { + pub fn to_activity(&self) -> Result { let mut ht = Hashtag::new(); ht.set_href( ap_url(&format!( @@ -55,7 +55,7 @@ impl Tag { ) } - pub fn build_activity07(tag: String) -> Result { + pub fn build_activity(tag: String) -> Result { let mut ht = Hashtag::new(); ht.set_href( ap_url(&format!( @@ -104,7 +104,7 @@ mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = &db(); conn.test_transaction::<_, Error, _>(|| { fill_database(conn); @@ -114,7 +114,7 @@ mod tests { is_hashtag: false, post_id: 0, }; - let act = tag.to_activity07()?; + let act = tag.to_activity()?; let expected = json!({ "href": "https://plu.me/tag/a_tag", "name": "a_tag", @@ -128,11 +128,11 @@ mod tests { } #[test] - fn build_activity07() { + fn build_activity() { let conn = &db(); conn.test_transaction::<_, Error, _>(|| { fill_database(conn); - let act = Tag::build_activity07("a_tag".into())?; + let act = Tag::build_activity("a_tag".into())?; let expected = json!({ "href": "https://plu.me/tag/a_tag", "name": "a_tag", diff --git a/plume-models/src/timeline/mod.rs b/plume-models/src/timeline/mod.rs index db7e3602..6507f293 100644 --- a/plume-models/src/timeline/mod.rs +++ b/plume-models/src/timeline/mod.rs @@ -623,10 +623,7 @@ mod tests { ) .unwrap(); gnu_post - .update_tags07( - &conn, - vec![Tag::build_activity07("free".to_owned()).unwrap()], - ) + .update_tags07(&conn, vec![Tag::build_activity("free".to_owned()).unwrap()]) .unwrap(); PostAuthor::insert( &conn, diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index d2e3ab1b..1ea5afdb 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -611,7 +611,7 @@ impl User { Ok(posts .into_iter() .filter_map(|p| { - p.create_activity07(conn) + p.create_activity(conn) .ok() .and_then(|a| serde_json::to_value(a).ok()) }) @@ -775,7 +775,7 @@ impl User { } } - pub fn to_activity07(&self, conn: &Connection) -> Result { + pub fn to_activity(&self, conn: &Connection) -> Result { let mut actor = ApActor::new(self.inbox_url.parse()?, Person::new()); let ap_url = self.ap_url.parse::()?; actor.set_id(ap_url.clone()); @@ -813,7 +813,7 @@ impl User { Ok(CustomPerson::new(actor, ap_signature)) } - pub fn delete_activity07(&self, conn: &Connection) -> Result { + pub fn delete_activity(&self, conn: &Connection) -> Result { let mut tombstone = Tombstone::new(); tombstone.set_id(self.ap_url.parse()?); @@ -1069,7 +1069,7 @@ impl AsObject for User { type Error = Error; type Output = (); - fn activity07(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { + fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> { if self.id == actor.id { self.delete(conn).map(|_| ()) } else { @@ -1426,7 +1426,7 @@ pub(crate) mod tests { conn.test_transaction::<_, (), _>(|| { let users = fill_database(&conn); - let ap_repr = users[0].to_activity07(&conn).unwrap(); + let ap_repr = users[0].to_activity(&conn).unwrap(); users[0].delete(&conn).unwrap(); let user = User::from_activity(&conn, ap_repr).unwrap(); @@ -1447,12 +1447,12 @@ pub(crate) mod tests { } #[test] - fn to_activity07() { + fn to_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let users = fill_database(&conn); let user = &users[0]; - let act = user.to_activity07(&conn)?; + let act = user.to_activity(&conn)?; let expected = json!({ "endpoints": { @@ -1477,7 +1477,7 @@ pub(crate) mod tests { assert_json_eq!(to_value(act)?, expected); let other = &users[2]; - let other_act = other.to_activity07(&conn)?; + let other_act = other.to_activity(&conn)?; let expected_other = json!({ "endpoints": { "sharedInbox": "https://plu.me/inbox" @@ -1509,12 +1509,12 @@ pub(crate) mod tests { } #[test] - fn delete_activity07() { + fn delete_activity() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let users = fill_database(&conn); let user = &users[1]; - let act = user.delete_activity07(&conn)?; + let act = user.delete_activity(&conn)?; let expected = json!({ "actor": "https://plu.me/@/user/", diff --git a/src/api/posts.rs b/src/api/posts.rs index d08d8d6a..56c80da9 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -193,14 +193,14 @@ pub fn create( for m in mentions.into_iter() { Mention::from_activity( &conn, - &Mention::build_activity07(&conn, &m)?, + &Mention::build_activity(&conn, &m)?, post.id, true, true, )?; } - let act = post.create_activity07(&conn)?; + let act = post.create_activity(&conn)?; let dest = User::one_by_instance(&conn)?; worker.execute(move || broadcast(&author, act, dest, CONFIG.proxy().cloned())); } diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index 1135d9ed..9ec851c0 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -49,7 +49,7 @@ pub fn activity_details( _ap: ApRequest, ) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; - Some(ActivityStream::new(blog.to_activity07(&conn).ok()?)) + Some(ActivityStream::new(blog.to_activity(&conn).ok()?)) } #[get("/blogs/new")] diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 5fd2cbcc..91a1ab0a 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -66,14 +66,14 @@ pub fn create( ) .expect("comments::create: insert error"); let new_comment = comm - .create_activity07(&conn) + .create_activity(&conn) .expect("comments::create: activity error"); // save mentions for ment in mentions { Mention::from_activity( &conn, - &Mention::build_activity07(&conn, &ment) + &Mention::build_activity(&conn, &ment) .expect("comments::create: build mention error"), comm.id, false, @@ -187,7 +187,7 @@ pub fn activity_pub( conn: DbConn, ) -> Option> { Comment::get(&conn, id) - .and_then(|c| c.to_activity07(&conn)) + .and_then(|c| c.to_activity(&conn)) .ok() .map(ActivityStream::new) } diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 06cf63cd..cedaa900 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -382,7 +382,7 @@ fn ban(id: i32, conn: &Connection, worker: &ScheduledThreadPool) -> Result<(), E ) .unwrap(); let target = User::one_by_instance(&*conn)?; - let delete_act = u.delete_activity07(&*conn)?; + let delete_act = u.delete_activity(&*conn)?; worker.execute(move || broadcast(&u, delete_act, target, CONFIG.proxy().cloned())); } diff --git a/src/routes/likes.rs b/src/routes/likes.rs index fc1c2970..cf141cb7 100644 --- a/src/routes/likes.rs +++ b/src/routes/likes.rs @@ -27,7 +27,7 @@ pub fn create( Timeline::add_to_all_timelines(&conn, &post, Kind::Like(&user))?; let dest = User::one_by_instance(&*conn)?; - let act = like.to_activity07(&*conn)?; + let act = like.to_activity(&*conn)?; rockets .worker .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 39209824..adb5d06c 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -113,7 +113,7 @@ pub fn activity_details( let post = Post::find_by_slug(&conn, &slug, blog.id).map_err(|_| None)?; if post.published { Ok(ActivityStream::new( - post.to_activity07(&conn) + post.to_activity(&conn) .map_err(|_| String::from("Post serialization error"))?, )) } else { @@ -312,7 +312,7 @@ pub fn update( &conn, mentions .into_iter() - .filter_map(|m| Mention::build_activity07(&conn, &m).ok()) + .filter_map(|m| Mention::build_activity(&conn, &m).ok()) .collect(), ) .expect("post::update: mentions error"); @@ -325,7 +325,7 @@ pub fn update( .filter(|t| !t.is_empty()) .collect::>() .into_iter() - .filter_map(|t| Tag::build_activity07(t.to_string()).ok()) + .filter_map(|t| Tag::build_activity(t.to_string()).ok()) .collect::>(); post.update_tags07(&conn, tags) .expect("post::update: tags error"); @@ -334,7 +334,7 @@ pub fn update( .into_iter() .collect::>() .into_iter() - .filter_map(|t| Tag::build_activity07(t).ok()) + .filter_map(|t| Tag::build_activity(t).ok()) .collect::>(); post.update_hashtags07(&conn, hashtags) .expect("post::update: hashtags error"); @@ -342,7 +342,7 @@ pub fn update( if post.published { if newly_published { let act = post - .create_activity07(&conn) + .create_activity(&conn) .expect("post::update: act error"); let dest = User::one_by_instance(&conn).expect("post::update: dest error"); rockets @@ -352,7 +352,7 @@ pub fn update( Timeline::add_to_all_timelines(&conn, &post, Kind::Original).ok(); } else { let act = post - .update_activity07(&conn) + .update_activity(&conn) .expect("post::update: act error"); let dest = User::one_by_instance(&conn).expect("posts::update: dest error"); rockets @@ -532,8 +532,7 @@ pub fn create( for m in mentions { Mention::from_activity( &conn, - &Mention::build_activity07(&conn, &m) - .expect("post::create: mention build error"), + &Mention::build_activity(&conn, &m).expect("post::create: mention build error"), post.id, true, true, @@ -542,7 +541,7 @@ pub fn create( } let act = post - .create_activity07(&conn) + .create_activity(&conn) .expect("posts::create: activity error"); let dest = User::one_by_instance(&conn).expect("posts::create: dest error"); let worker = &rockets.worker; diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index e815486b..120673d5 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -27,7 +27,7 @@ pub fn create( Timeline::add_to_all_timelines(&conn, &post, Kind::Reshare(&user))?; let dest = User::one_by_instance(&conn)?; - let act = reshare.to_activity07(&conn)?; + let act = reshare.to_activity(&conn)?; rockets .worker .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); diff --git a/src/routes/user.rs b/src/routes/user.rs index 259aaf4d..b9e836bb 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -125,7 +125,7 @@ pub fn follow( )?; f.notify(&conn)?; - let act = f.to_activity07(&conn)?; + let act = f.to_activity(&conn)?; let msg = i18n!(rockets.intl.catalog, "You are now following {}."; target.name()); rockets .worker @@ -271,7 +271,7 @@ pub fn activity_details( _ap: ApRequest, ) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; - Some(ActivityStream::new(user.to_activity07(&conn).ok()?)) + Some(ActivityStream::new(user.to_activity(&conn).ok()?)) } #[get("/users/new")] @@ -386,7 +386,7 @@ pub fn delete( account.delete(&conn)?; let target = User::one_by_instance(&conn)?; - let delete_act = account.delete_activity07(&conn)?; + let delete_act = account.delete_activity(&conn)?; rockets .worker .execute(move || broadcast(&account, delete_act, target, CONFIG.proxy().cloned())); From e6ea302319f087d50bde7fc64db9b583a17e3948 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:31:35 +0900 Subject: [PATCH 208/233] Remove activitypub crate from Inbox test --- plume-common/src/activity_pub/inbox.rs | 78 +++++++++----------------- 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index fd89fa40..21892d7d 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -549,14 +549,11 @@ mod tests { use crate::activity_pub::sign::{ gen_keypair, Error as SignError, Result as SignResult, Signer, }; - use activitypub::{activity::*, actor::Person, object::Note}; use activitystreams::{ - activity::{ - Announce as Announce07, Create as Create07, Delete as Delete07, Like as Like07, - }, - actor::Person as Person07, + activity::{Announce, Create, Delete, Like}, + actor::Person, base::Base, - object::Note as Note07, + object::Note, prelude::*, }; use once_cell::sync::Lazy; @@ -604,13 +601,13 @@ mod tests { struct MyActor; impl FromId<()> for MyActor { type Error = (); - type Object = Person07; + type Object = Person; fn from_db(_: &(), _id: &str) -> Result { Ok(Self) } - fn from_activity(_: &(), _obj: Person07) -> Result { + fn from_activity(_: &(), _obj: Person) -> Result { Ok(Self) } @@ -632,13 +629,13 @@ mod tests { struct MyObject07; impl FromId<()> for MyObject07 { type Error = (); - type Object = Note07; + type Object = Note; fn from_db(_: &(), _id: &str) -> Result { Ok(Self) } - fn from_activity(_: &(), _obj: Note07) -> Result { + fn from_activity(_: &(), _obj: Note) -> Result { Ok(Self) } @@ -646,7 +643,7 @@ mod tests { &*MY_SIGNER } } - impl AsObject for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -656,7 +653,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -666,7 +663,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -676,7 +673,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -686,31 +683,12 @@ mod tests { } } - fn build_create() -> Create { - let mut act = Create::default(); - act.object_props - .set_id_string(String::from("https://test.ap/activity")) - .unwrap(); - let mut person = Person::default(); - person - .object_props - .set_id_string(String::from("https://test.ap/actor")) - .unwrap(); - act.create_props.set_actor_object(person).unwrap(); - let mut note = Note::default(); - note.object_props - .set_id_string(String::from("https://test.ap/note")) - .unwrap(); - act.create_props.set_object_object(note).unwrap(); - act - } - - fn build_create07() -> Create07 { - let mut person = Person07::new(); + fn build_create07() -> Create { + let mut person = Person::new(); person.set_id("https://test.ap/actor".parse().unwrap()); - let mut note = Note07::new(); + let mut note = Note::new(); note.set_id("https://test.ap/note".parse().unwrap()); - let mut act = Create07::new( + let mut act = Create::new( Base::retract(person).unwrap().into_generic().unwrap(), Base::retract(note).unwrap().into_generic().unwrap(), ); @@ -722,19 +700,19 @@ mod tests { fn test_inbox_basic07() { let act = serde_json::to_value(build_create07()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } #[test] fn test_inbox_multi_handlers07() { - let act = serde_json::to_value(build_create()).unwrap(); + let act = serde_json::to_value(build_create07()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .with::(None) - .with::(None) - .with::(None) + .with::(None) + .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } @@ -744,8 +722,8 @@ mod tests { let act = serde_json::to_value(build_create07()).unwrap(); // Create is not handled by this inbox let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_err()); } @@ -763,7 +741,7 @@ mod tests { impl FromId<()> for FailingActor { type Error = (); - type Object = Person07; + type Object = Person; fn from_db(_: &(), _id: &str) -> Result { Err(()) @@ -778,7 +756,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject07 { type Error = (); type Output = (); @@ -798,13 +776,13 @@ mod tests { let act = serde_json::to_value(build_create07()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with::(None) + .with::(None) .done(); assert!(res.is_err()); let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with::(None) - .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } From d75600ba14139b883c8beeeb13e0e6295b9e38a5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 01:32:47 +0900 Subject: [PATCH 209/233] Remove trailing 07 in activity_pub/inbox.rs --- plume-common/src/activity_pub/inbox.rs | 52 +++++++++++++------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 21892d7d..845a98c7 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -626,8 +626,8 @@ mod tests { } } - struct MyObject07; - impl FromId<()> for MyObject07 { + struct MyObject; + impl FromId<()> for MyObject { type Error = (); type Object = Note; @@ -643,7 +643,7 @@ mod tests { &*MY_SIGNER } } - impl AsObject for MyObject07 { + impl AsObject for MyObject { type Error = (); type Output = (); @@ -653,7 +653,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject { type Error = (); type Output = (); @@ -663,7 +663,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject { type Error = (); type Output = (); @@ -673,7 +673,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject { type Error = (); type Output = (); @@ -683,7 +683,7 @@ mod tests { } } - fn build_create07() -> Create { + fn build_create() -> Create { let mut person = Person::new(); person.set_id("https://test.ap/actor".parse().unwrap()); let mut note = Note::new(); @@ -697,33 +697,33 @@ mod tests { } #[test] - fn test_inbox_basic07() { - let act = serde_json::to_value(build_create07()).unwrap(); + fn test_inbox_basic() { + let act = serde_json::to_value(build_create()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } #[test] - fn test_inbox_multi_handlers07() { - let act = serde_json::to_value(build_create07()).unwrap(); + fn test_inbox_multi_handlers() { + let act = serde_json::to_value(build_create()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .with::(None) - .with::(None) - .with::(None) + .with::(None) + .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } #[test] - fn test_inbox_failure07() { - let act = serde_json::to_value(build_create07()).unwrap(); + fn test_inbox_failure() { + let act = serde_json::to_value(build_create()).unwrap(); // Create is not handled by this inbox let res: Result<(), ()> = Inbox::handle(&(), act) - .with::(None) - .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_err()); } @@ -756,7 +756,7 @@ mod tests { } } - impl AsObject for MyObject07 { + impl AsObject for MyObject { type Error = (); type Output = (); @@ -772,17 +772,17 @@ mod tests { } #[test] - fn test_inbox_actor_failure07() { - let act = serde_json::to_value(build_create07()).unwrap(); + fn test_inbox_actor_failure() { + let act = serde_json::to_value(build_create()).unwrap(); let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with::(None) + .with::(None) .done(); assert!(res.is_err()); let res: Result<(), ()> = Inbox::handle(&(), act.clone()) - .with::(None) - .with::(None) + .with::(None) + .with::(None) .done(); assert!(res.is_ok()); } From 6282b98b0309dc4ffeeeebf5b8d28dbe17e951a7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:05:46 +0900 Subject: [PATCH 210/233] Fix doc test --- plume-common/src/activity_pub/inbox.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs index 845a98c7..2a77c28c 100644 --- a/plume-common/src/activity_pub/inbox.rs +++ b/plume-common/src/activity_pub/inbox.rs @@ -10,8 +10,7 @@ use super::{request, sign::Signer}; /// # Example /// /// ```rust -/// # extern crate activitypub; -/// # use activitypub::{actor::Person, activity::{Announce, Create}, object::Note}; +/// # use activitystreams::{prelude::*, base::Base, actor::Person, activity::{Announce, Create}, object::Note, iri_string::types::IriString}; /// # use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa}; /// # use once_cell::sync::Lazy; /// # use plume_common::activity_pub::inbox::*; @@ -113,12 +112,13 @@ use super::{request, sign::Signer}; /// # } /// # } /// # -/// # let mut act = Create::default(); -/// # act.object_props.set_id_string(String::from("https://test.ap/activity")).unwrap(); -/// # let mut person = Person::default(); -/// # person.object_props.set_id_string(String::from("https://test.ap/actor")).unwrap(); -/// # act.create_props.set_actor_object(person).unwrap(); -/// # act.create_props.set_object_object(Note::default()).unwrap(); +/// # let mut person = Person::new(); +/// # person.set_id("https://test.ap/actor".parse::().unwrap()); +/// # let mut act = Create::new( +/// # Base::retract(person).unwrap().into_generic().unwrap(), +/// # Base::retract(Note::new()).unwrap().into_generic().unwrap() +/// # ); +/// # act.set_id("https://test.ap/activity".parse::().unwrap()); /// # let activity_json = serde_json::to_value(act).unwrap(); /// # /// # let conn = (); @@ -418,8 +418,7 @@ pub trait AsActor { /// representing the Note by a Message type, without any specific context. /// /// ```rust -/// # extern crate activitypub; -/// # use activitypub::{activity::Create, actor::Person, object::Note}; +/// # use activitystreams::{prelude::*, activity::Create, actor::Person, object::Note}; /// # use plume_common::activity_pub::inbox::{AsActor, AsObject, FromId}; /// # use plume_common::activity_pub::sign::{gen_keypair, Error as SignError, Result as SignResult, Signer}; /// # use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa}; @@ -501,7 +500,10 @@ pub trait AsActor { /// } /// /// fn from_activity(_: &(), obj: Note) -> Result { -/// Ok(Message { text: obj.object_props.content_string().map_err(|_| ())? }) +/// Ok(Message { +/// text: obj.content() +/// .and_then(|content| content.to_owned().single_xsd_string()).ok_or(())? +/// }) /// } /// /// fn get_sender() -> &'static dyn Signer { From d23002b8171fed01a3649ca63cf9aa30031c78e4 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:11:46 +0900 Subject: [PATCH 211/233] Remove trailing 07 from method name --- plume-models/src/blogs.rs | 22 ++++++++++---------- plume-models/src/comments.rs | 10 ++++----- plume-models/src/follows.rs | 20 +++++++++--------- plume-models/src/likes.rs | 6 +++--- plume-models/src/posts.rs | 20 +++++++++--------- plume-models/src/remote_fetch_actor.rs | 2 +- plume-models/src/reshares.rs | 6 +++--- plume-models/src/timeline/mod.rs | 2 +- plume-models/src/users.rs | 28 +++++++++++++------------- src/routes/blogs.rs | 4 ++-- src/routes/comments.rs | 2 +- src/routes/likes.rs | 2 +- src/routes/posts.rs | 8 ++++---- src/routes/reshares.rs | 2 +- src/routes/user.rs | 6 +++--- 15 files changed, 70 insertions(+), 70 deletions(-) diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index 4deb71c6..ac20ee86 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -221,10 +221,10 @@ impl Blog { Ok(CustomGroup::new(blog, ap_signature, source)) } - pub fn outbox07(&self, conn: &Connection) -> Result> { - self.outbox_collection07(conn).map(ActivityStream::new) + pub fn outbox(&self, conn: &Connection) -> Result> { + self.outbox_collection(conn).map(ActivityStream::new) } - pub fn outbox_collection07(&self, conn: &Connection) -> Result { + pub fn outbox_collection(&self, conn: &Connection) -> Result { let acts = self.get_activities(conn); let acts = acts .iter() @@ -245,15 +245,15 @@ impl Blog { ); Ok(coll) } - pub fn outbox_page07( + pub fn outbox_page( &self, conn: &Connection, (min, max): (i32, i32), ) -> Result> { - self.outbox_collection_page07(conn, (min, max)) + self.outbox_collection_page(conn, (min, max)) .map(ActivityStream::new) } - pub fn outbox_collection_page07( + pub fn outbox_collection_page( &self, conn: &Connection, (min, max): (i32, i32), @@ -917,7 +917,7 @@ pub(crate) mod tests { } #[test] - fn self_federation07() { + fn self_federation() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let (users, mut blogs) = fill_database(&conn); @@ -1019,12 +1019,12 @@ pub(crate) mod tests { } #[test] - fn outbox_collection07() { + fn outbox_collection() { let conn = &db(); conn.test_transaction::<_, Error, _>(|| { let (_users, blogs) = fill_database(conn); let blog = &blogs[0]; - let act = blog.outbox_collection07(conn)?; + let act = blog.outbox_collection(conn)?; let expected = json!({ "items": [], @@ -1041,12 +1041,12 @@ pub(crate) mod tests { } #[test] - fn outbox_collection_page07() { + fn outbox_collection_page() { let conn = &db(); conn.test_transaction::<_, Error, _>(|| { let (_users, blogs) = fill_database(conn); let blog = &blogs[0]; - let act = blog.outbox_collection_page07(conn, (33, 36))?; + let act = blog.outbox_collection_page(conn, (33, 36))?; let expected = json!({ "next": "https://plu.me/~/BlogName/outbox?page=3", diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 03944b3b..d928b9a3 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -196,7 +196,7 @@ impl Comment { Ok(()) } - pub fn build_delete07(&self, conn: &Connection) -> Result { + pub fn build_delete(&self, conn: &Connection) -> Result { let mut tombstone = Tombstone::new(); tombstone.set_id( self.ap_url @@ -454,7 +454,7 @@ mod tests { // creates a post, get it's Create activity, delete the post, // "send" the Create to the inbox, and check it works #[test] - fn self_federation07() { + fn self_federation() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let (original_comm, posts, users, _blogs) = prepare_activity(&conn); @@ -523,7 +523,7 @@ mod tests { inbox( &conn, - serde_json::to_value(original_comm.build_delete07(&conn).unwrap()).unwrap(), + serde_json::to_value(original_comm.build_delete(&conn).unwrap()).unwrap(), ) .unwrap(); @@ -576,11 +576,11 @@ mod tests { } #[test] - fn build_delete07() { + fn build_delete() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (comment, _posts, _users, _blogs) = prepare_activity(&conn); - let act = comment.build_delete07(&conn)?; + let act = comment.build_delete(&conn)?; let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index c8ebe843..2a334767 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -84,7 +84,7 @@ impl Follow { /// from -> The one sending the follow request /// target -> The target of the request, responding with Accept - pub fn accept_follow07 + IntoId, T>( + pub fn accept_follow + IntoId, T>( conn: &Connection, from: &B, target: &A, @@ -105,7 +105,7 @@ impl Follow { )?; res.notify(conn)?; - let accept = res.build_accept07(from, target, follow)?; + let accept = res.build_accept(from, target, follow)?; broadcast( &*target, accept, @@ -115,7 +115,7 @@ impl Follow { Ok(res) } - pub fn build_accept07 + IntoId, T>( + pub fn build_accept + IntoId, T>( &self, from: &B, target: &A, @@ -137,7 +137,7 @@ impl Follow { Ok(accept) } - pub fn build_undo07(&self, conn: &Connection) -> Result { + pub fn build_undo(&self, conn: &Connection) -> Result { let mut undo = Undo::new( User::get(conn, self.follower_id)? .ap_url @@ -164,7 +164,7 @@ impl AsObject for User { let mut follow = FollowAct::new(id.parse::()?, actor.ap_url.parse::()?); follow.set_id(id.parse::()?); - Follow::accept_follow07(conn, &actor, &self, follow, actor.id, self.id) + Follow::accept_follow(conn, &actor, &self, follow, actor.id, self.id) } } @@ -200,7 +200,7 @@ impl FromId for Follow { CONFIG.proxy(), ) .map_err(|(_, e)| e)?; - Follow::accept_follow07(conn, &actor, &target, follow, actor.id, target.id) + Follow::accept_follow(conn, &actor, &target, follow, actor.id, target.id) } fn get_sender() -> &'static dyn Signer { @@ -319,11 +319,11 @@ mod tests { } #[test] - fn build_accept07() { + fn build_accept() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (follow, following, follower, _users) = prepare_activity(&conn); - let act = follow.build_accept07(&follower, &following, follow.to_activity(&conn)?)?; + let act = follow.build_accept(&follower, &following, follow.to_activity(&conn)?)?; let expected = json!({ "actor": "https://plu.me/@/user/", @@ -348,11 +348,11 @@ mod tests { } #[test] - fn build_undo07() { + fn build_undo() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (follow, _following, _follower, _users) = prepare_activity(&conn); - let act = follow.build_undo07(&conn)?; + let act = follow.build_undo(&conn)?; let expected = json!({ "actor": "https://plu.me/@/other/", diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index b6ff9421..b9dda167 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -70,7 +70,7 @@ impl Like { Ok(()) } - pub fn build_undo07(&self, conn: &Connection) -> Result { + pub fn build_undo(&self, conn: &Connection) -> Result { let mut act = Undo::new( User::get(conn, self.user_id)?.ap_url.parse::()?, AnyBase::from_extended(self.to_activity(conn)?)?, @@ -217,14 +217,14 @@ mod tests { } #[test] - fn build_undo07() { + fn build_undo() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (posts, _users, _blogs) = fill_database(&conn); let post = &posts[0]; let user = &post.get_authors(&conn)?[0]; let like = Like::insert(&*conn, NewLike::new(post, user))?; - let act = like.build_undo07(&*conn)?; + let act = like.build_undo(&*conn)?; let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index dfa15a72..58a203f7 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -445,7 +445,7 @@ impl Post { Ok(act) } - pub fn update_mentions07(&self, conn: &Connection, mentions: Vec) -> Result<()> { + pub fn update_mentions(&self, conn: &Connection, mentions: Vec) -> Result<()> { let mentions = mentions .into_iter() .map(|m| { @@ -483,7 +483,7 @@ impl Post { Ok(()) } - pub fn update_tags07(&self, conn: &Connection, tags: Vec) -> Result<()> { + pub fn update_tags(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() .filter_map(|t| t.name.as_ref().map(|name| name.as_str().to_string())) @@ -520,7 +520,7 @@ impl Post { Ok(()) } - pub fn update_hashtags07(&self, conn: &Connection, tags: Vec) -> Result<()> { + pub fn update_hashtags(&self, conn: &Connection, tags: Vec) -> Result<()> { let tags_name = tags .iter() .filter_map(|t| t.name.as_ref().map(|name| name.as_str().to_string())) @@ -568,7 +568,7 @@ impl Post { .and_then(|c| c.url().ok()) } - pub fn build_delete07(&self, conn: &Connection) -> Result { + pub fn build_delete(&self, conn: &Connection) -> Result { let mut tombstone = Tombstone::new(); tombstone.set_id(self.ap_url.parse()?); @@ -968,9 +968,9 @@ impl AsObject for PostUpdate { }) .ok(); } - post.update_mentions07(conn, mentions)?; - post.update_tags07(conn, tags)?; - post.update_hashtags07(conn, hashtags)?; + post.update_mentions(conn, mentions)?; + post.update_tags(conn, tags)?; + post.update_hashtags(conn, hashtags)?; } post.update(conn)?; @@ -1033,7 +1033,7 @@ mod tests { // creates a post, get it's Create activity, delete the post, // "send" the Create to the inbox, and check it works #[test] - fn self_federation07() { + fn self_federation() { let conn = &db(); conn.test_transaction::<_, (), _>(|| { let (_, users, blogs) = fill_database(&conn); @@ -1230,11 +1230,11 @@ mod tests { } #[test] - fn build_delete07() { + fn build_delete() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (post, _mention, _posts, _users, _blogs) = prepare_activity(&conn); - let act = post.build_delete07(&conn)?; + let act = post.build_delete(&conn)?; let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index 228671e3..03f1dd76 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -68,7 +68,7 @@ impl ActorFactoryArgs for RemoteFetchActor { } fn fetch_and_cache_articles(user: &Arc, conn: &DbConn) { - let create_acts = user.fetch_outbox07::(); + let create_acts = user.fetch_outbox::(); match create_acts { Ok(create_acts) => { for create_act in create_acts { diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index e0d973ab..aec75796 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -97,7 +97,7 @@ impl Reshare { Ok(()) } - pub fn build_undo07(&self, conn: &Connection) -> Result { + pub fn build_undo(&self, conn: &Connection) -> Result { let mut act = Undo::new( User::get(conn, self.user_id)?.ap_url.parse::()?, AnyBase::from_extended(self.to_activity(conn)?)?, @@ -247,14 +247,14 @@ mod test { } #[test] - fn build_undo07() { + fn build_undo() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (posts, _users, _blogs) = fill_database(&conn); let post = &posts[0]; let user = &post.get_authors(&conn)?[0]; let reshare = Reshare::insert(&*conn, NewReshare::new(post, user))?; - let act = reshare.build_undo07(&*conn)?; + let act = reshare.build_undo(&*conn)?; let expected = json!({ "actor": "https://plu.me/@/admin/", diff --git a/plume-models/src/timeline/mod.rs b/plume-models/src/timeline/mod.rs index 6507f293..d6b2a59d 100644 --- a/plume-models/src/timeline/mod.rs +++ b/plume-models/src/timeline/mod.rs @@ -623,7 +623,7 @@ mod tests { ) .unwrap(); gnu_post - .update_tags07(&conn, vec![Tag::build_activity("free".to_owned()).unwrap()]) + .update_tags(&conn, vec![Tag::build_activity("free".to_owned()).unwrap()]) .unwrap(); PostAuthor::insert( &conn, diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 1ea5afdb..3086b7a8 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -460,10 +460,10 @@ impl User { .load::(conn) .map_err(Error::from) } - pub fn outbox07(&self, conn: &Connection) -> Result> { - Ok(ActivityStream::new(self.outbox_collection07(conn)?)) + pub fn outbox(&self, conn: &Connection) -> Result> { + Ok(ActivityStream::new(self.outbox_collection(conn)?)) } - pub fn outbox_collection07(&self, conn: &Connection) -> Result { + pub fn outbox_collection(&self, conn: &Connection) -> Result { let mut coll = OrderedCollection::new(); let first = &format!("{}?page=1", &self.outbox_url); let last = &format!( @@ -476,16 +476,16 @@ impl User { coll.set_total_items(self.get_activities_count(conn) as u64); Ok(coll) } - pub fn outbox_page07( + pub fn outbox_page( &self, conn: &Connection, (min, max): (i32, i32), ) -> Result> { Ok(ActivityStream::new( - self.outbox_collection_page07(conn, (min, max))?, + self.outbox_collection_page(conn, (min, max))?, )) } - pub fn outbox_collection_page07( + pub fn outbox_collection_page( &self, conn: &Connection, (min, max): (i32, i32), @@ -513,7 +513,7 @@ impl User { Ok(coll) } - pub fn fetch_outbox_page07( + pub fn fetch_outbox_page( &self, url: &str, ) -> Result<(Vec, Option)> { @@ -531,7 +531,7 @@ impl User { Ok((items, next)) } - pub fn fetch_outbox07(&self) -> Result> { + pub fn fetch_outbox(&self) -> Result> { let mut res = get( &self.outbox_url[..], Self::get_sender(), @@ -542,7 +542,7 @@ impl User { if let Some(first) = json.get("first") { let mut items: Vec = Vec::new(); let mut next = first.as_str().unwrap().to_owned(); - while let Ok((mut page, nxt)) = self.fetch_outbox_page07(&next) { + while let Ok((mut page, nxt)) = self.fetch_outbox_page(&next) { if page.is_empty() { break; } @@ -1421,7 +1421,7 @@ pub(crate) mod tests { } #[test] - fn self_federation07() { + fn self_federation() { let conn = db(); conn.test_transaction::<_, (), _>(|| { let users = fill_database(&conn); @@ -1535,12 +1535,12 @@ pub(crate) mod tests { } #[test] - fn outbox_collection07() { + fn outbox_collection() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let (_pages, users, _blogs) = fill_pages(&conn); let user = &users[0]; - let act = user.outbox_collection07(&conn)?; + let act = user.outbox_collection(&conn)?; let expected = json!({ "first": "https://plu.me/@/admin/outbox?page=1", @@ -1556,12 +1556,12 @@ pub(crate) mod tests { } #[test] - fn outbox_collection_page07() { + fn outbox_collection_page() { let conn = db(); conn.test_transaction::<_, Error, _>(|| { let users = fill_database(&conn); let user = &users[0]; - let act = user.outbox_collection_page07(&conn, (33, 36))?; + let act = user.outbox_collection_page(&conn, (33, 36))?; let expected = json!({ "items": [], diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index 9ec851c0..7359779a 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -349,7 +349,7 @@ pub fn update( #[get("/~//outbox")] pub fn outbox(name: String, conn: DbConn) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; - blog.outbox07(&conn).ok() + blog.outbox(&conn).ok() } #[allow(unused_variables)] #[get("/~//outbox?")] @@ -359,7 +359,7 @@ pub fn outbox_page( conn: DbConn, ) -> Option> { let blog = Blog::find_by_fqn(&conn, &name).ok()?; - blog.outbox_page07(&conn, page.limits()).ok() + blog.outbox_page(&conn, page.limits()).ok() } #[get("/~//atom.xml")] pub fn atom_feed(name: String, conn: DbConn) -> Option> { diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 91a1ab0a..5f60aae3 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -150,7 +150,7 @@ pub fn delete( if let Ok(comment) = Comment::get(&conn, id) { if comment.author_id == user.id { let dest = User::one_by_instance(&conn)?; - let delete_activity = comment.build_delete07(&conn)?; + let delete_activity = comment.build_delete(&conn)?; inbox( &conn, serde_json::to_value(&delete_activity).map_err(Error::from)?, diff --git a/src/routes/likes.rs b/src/routes/likes.rs index cf141cb7..25ca68bf 100644 --- a/src/routes/likes.rs +++ b/src/routes/likes.rs @@ -33,7 +33,7 @@ pub fn create( .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } else { let like = likes::Like::find_by_user_on_post(&conn, user.id, post.id)?; - let delete_act = like.build_undo07(&conn)?; + let delete_act = like.build_undo(&conn)?; inbox( &conn, serde_json::to_value(&delete_act).map_err(Error::from)?, diff --git a/src/routes/posts.rs b/src/routes/posts.rs index adb5d06c..5d498f8c 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -308,7 +308,7 @@ pub fn update( post.update(&conn).expect("post::update: update error"); if post.published { - post.update_mentions07( + post.update_mentions( &conn, mentions .into_iter() @@ -327,7 +327,7 @@ pub fn update( .into_iter() .filter_map(|t| Tag::build_activity(t.to_string()).ok()) .collect::>(); - post.update_tags07(&conn, tags) + post.update_tags(&conn, tags) .expect("post::update: tags error"); let hashtags = hashtags @@ -336,7 +336,7 @@ pub fn update( .into_iter() .filter_map(|t| Tag::build_activity(t).ok()) .collect::>(); - post.update_hashtags07(&conn, hashtags) + post.update_hashtags(&conn, hashtags) .expect("post::update: hashtags error"); if post.published { @@ -606,7 +606,7 @@ pub fn delete( } let dest = User::one_by_instance(&conn)?; - let delete_activity = post.build_delete07(&conn)?; + let delete_activity = post.build_delete(&conn)?; inbox( &conn, serde_json::to_value(&delete_activity).map_err(Error::from)?, diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index 120673d5..b6d11c8a 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -33,7 +33,7 @@ pub fn create( .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); } else { let reshare = Reshare::find_by_user_on_post(&conn, user.id, post.id)?; - let delete_act = reshare.build_undo07(&conn)?; + let delete_act = reshare.build_undo(&conn)?; inbox( &conn, serde_json::to_value(&delete_act).map_err(Error::from)?, diff --git a/src/routes/user.rs b/src/routes/user.rs index b9e836bb..443cb151 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -103,7 +103,7 @@ pub fn follow( ) -> Result, ErrorPage> { let target = User::find_by_fqn(&conn, &name)?; let message = if let Ok(follow) = follows::Follow::find(&conn, user.id, target.id) { - let delete_act = follow.build_undo07(&conn)?; + let delete_act = follow.build_undo(&conn)?; local_inbox( &conn, serde_json::to_value(&delete_act).map_err(Error::from)?, @@ -531,7 +531,7 @@ pub fn create( #[get("/@//outbox")] pub fn outbox(name: String, conn: DbConn) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; - user.outbox07(&conn).ok() + user.outbox(&conn).ok() } #[get("/@//outbox?")] pub fn outbox_page( @@ -540,7 +540,7 @@ pub fn outbox_page( conn: DbConn, ) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; - user.outbox_page07(&conn, page.limits()).ok() + user.outbox_page(&conn, page.limits()).ok() } #[post("/@//inbox", data = "")] pub fn inbox( From 9b04fb96e65e8838dd30b4a6f4c754e6ecb01462 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:12:59 +0900 Subject: [PATCH 212/233] Remote trailing 07 in inbox.rs --- plume-models/src/inbox.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index 86472590..fdf4056e 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -1,7 +1,4 @@ -use activitystreams::activity::{ - Announce as Announce07, Create as Create07, Delete as Delete07, Follow as Follow07, - Like as Like07, Undo as Undo07, Update as Update07, -}; +use activitystreams::activity::{Announce, Create, Delete, Follow, Like, Undo, Update}; use crate::{ comments::Comment, @@ -51,18 +48,18 @@ impl_into_inbox_result! { pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result { Inbox::handle(conn, act) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) - .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) + .with::(CONFIG.proxy()) .done() } From 78a001ac8911d5b1ebb69245e3fc038004990d5e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:14:16 +0900 Subject: [PATCH 213/233] Remove trailing 07 in routes/posts.rs --- src/routes/posts.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 5d498f8c..09b097b8 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -15,9 +15,7 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{ - broadcast, ActivityStream, ApRequest, LicensedArticle as LicensedArticle07, -}; +use plume_common::activity_pub::{broadcast, ActivityStream, ApRequest, LicensedArticle}; use plume_common::utils::md_to_html; use plume_models::{ blogs::*, @@ -108,7 +106,7 @@ pub fn activity_details( slug: String, _ap: ApRequest, conn: DbConn, -) -> Result, Option> { +) -> Result, Option> { let blog = Blog::find_by_fqn(&conn, &blog).map_err(|_| None)?; let post = Post::find_by_slug(&conn, &slug, blog.id).map_err(|_| None)?; if post.published { From b17884681d56e149799d39451ffa97dd29fc67f3 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:50:14 +0900 Subject: [PATCH 214/233] Implement ap_followers using activitystreams --- src/routes/user.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/routes/user.rs b/src/routes/user.rs index 443cb151..e1b1cfdd 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -1,6 +1,7 @@ -use activitypub::collection::OrderedCollection; -use activitystreams::collection::{ - OrderedCollection as OrderedCollection07, OrderedCollectionPage, +use activitystreams::{ + collection::{OrderedCollection, OrderedCollectionPage}, + iri_string::types::IriString, + prelude::*, }; use diesel::SaveChangesDsl; use rocket::{ @@ -18,7 +19,7 @@ use crate::routes::{ }; use crate::template_utils::{IntoContext, Ructe}; use crate::utils::requires_login; -use plume_common::activity_pub::{broadcast, ActivityStream, ApRequest, CustomPerson, Id}; +use plume_common::activity_pub::{broadcast, ActivityStream, ApRequest, CustomPerson}; use plume_common::utils::md_to_html; use plume_models::{ blogs::Blog, @@ -529,7 +530,7 @@ pub fn create( } #[get("/@//outbox")] -pub fn outbox(name: String, conn: DbConn) -> Option> { +pub fn outbox(name: String, conn: DbConn) -> Option> { let user = User::find_by_fqn(&conn, &name).ok()?; user.outbox(&conn).ok() } @@ -564,17 +565,13 @@ pub fn ap_followers( .get_followers(&conn) .ok()? .into_iter() - .map(|f| Id::new(f.ap_url)) - .collect::>(); + .filter_map(|f| f.ap_url.parse::().ok()) + .collect::>(); - let mut coll = OrderedCollection::default(); - coll.object_props - .set_id_string(user.followers_endpoint) - .ok()?; - coll.collection_props - .set_total_items_u64(followers.len() as u64) - .ok()?; - coll.collection_props.set_items_link_vec(followers).ok()?; + let mut coll = OrderedCollection::new(); + coll.set_id(user.followers_endpoint.parse::().ok()?); + coll.set_total_items(followers.len() as u64); + coll.set_many_items(followers); Some(ActivityStream::new(coll)) } From d96940c848e484a60695f0cc10d424d3ccaa8f96 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:51:36 +0900 Subject: [PATCH 215/233] Don't implement activitypub::Link for Id --- plume-common/src/activity_pub/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index f2d1da06..2940add7 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,4 +1,3 @@ -use activitypub::Link; use activitystreams::{ actor::{ApActor, Group, Person}, base::{AnyBase, Base, Extends}, @@ -215,8 +214,6 @@ pub trait IntoId { fn into_id(self) -> Id; } -impl Link for Id {} - #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ApSignature { From 52022fb59708b84e26b1ede485ce522585a0b6bf Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 02:54:08 +0900 Subject: [PATCH 216/233] Remove activitypub crate from plume-models --- plume-models/src/lib.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plume-models/src/lib.rs b/plume-models/src/lib.rs index 0720599b..c9c991b4 100644 --- a/plume-models/src/lib.rs +++ b/plume-models/src/lib.rs @@ -125,15 +125,6 @@ impl From for Error { } } -impl From for Error { - fn from(err: activitypub::Error) -> Self { - match err { - activitypub::Error::NotFound => Error::MissingApProperty, - _ => Error::SerDe, - } - } -} - impl From for Error { fn from(_: activitystreams::checked::CheckError) -> Error { Error::MissingApProperty From 3d434f19236dbf1971a3e48f3372dbc637e7334a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 03:05:26 +0900 Subject: [PATCH 217/233] Remove old activitypub related crates --- Cargo.lock | 85 ----------------------------------------- Cargo.toml | 1 - plume-common/Cargo.toml | 3 -- plume-models/Cargo.toml | 1 - 4 files changed, 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 291f450f..abd788ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,20 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "activitypub" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bfd311e7b4102971757a2a6f143a93b1a8e6b5afc2c46936af827fd9eab403f" -dependencies = [ - "activitystreams-derive", - "activitystreams-traits", - "activitystreams-types", - "serde 1.0.136", - "serde_derive", - "serde_json", -] - [[package]] name = "activitystreams" version = "0.7.0-alpha.20" @@ -30,17 +16,6 @@ dependencies = [ "time 0.3.9", ] -[[package]] -name = "activitystreams-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176bdecfca82b1980e4769e3d54b6a392284b724083e0bff68272e290f17458f" -dependencies = [ - "proc-macro2 0.3.8", - "quote 0.5.2", - "syn 0.13.11", -] - [[package]] name = "activitystreams-ext" version = "0.1.0-alpha.2" @@ -62,32 +37,6 @@ dependencies = [ "serde 1.0.136", ] -[[package]] -name = "activitystreams-traits" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ef03168e704b0cae242e7a5d8b40506772b339687e01a3496fc4afe2e8542" -dependencies = [ - "failure", - "serde 1.0.136", - "serde_json", -] - -[[package]] -name = "activitystreams-types" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff74c5765278614a009f97b9ec12f9a7c732bbcc5e0337fcfcab619b784860ec" -dependencies = [ - "activitystreams-derive", - "activitystreams-traits", - "chrono", - "mime 0.3.16", - "serde 1.0.136", - "serde_derive", - "serde_json", -] - [[package]] name = "addr2line" version = "0.17.0" @@ -3156,7 +3105,6 @@ dependencies = [ name = "plume" version = "0.7.1" dependencies = [ - "activitypub", "activitystreams", "atom_syndication", "chrono", @@ -3214,11 +3162,8 @@ dependencies = [ name = "plume-common" version = "0.7.1" dependencies = [ - "activitypub", "activitystreams", - "activitystreams-derive", "activitystreams-ext", - "activitystreams-traits", "array_tool", "askama_escape", "assert-json-diff", @@ -3271,7 +3216,6 @@ dependencies = [ name = "plume-models" version = "0.7.1" dependencies = [ - "activitypub", "activitystreams", "ammonia", "assert-json-diff", @@ -3397,15 +3341,6 @@ dependencies = [ "unicode-xid 0.1.0", ] -[[package]] -name = "proc-macro2" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -dependencies = [ - "unicode-xid 0.1.0", -] - [[package]] name = "proc-macro2" version = "0.4.30" @@ -3469,15 +3404,6 @@ dependencies = [ "proc-macro2 0.2.3", ] -[[package]] -name = "quote" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -dependencies = [ - "proc-macro2 0.3.8", -] - [[package]] name = "quote" version = "0.6.13" @@ -4437,17 +4363,6 @@ dependencies = [ "unicode-xid 0.1.0", ] -[[package]] -name = "syn" -version = "0.13.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" -dependencies = [ - "proc-macro2 0.3.8", - "quote 0.5.2", - "unicode-xid 0.1.0", -] - [[package]] name = "syn" version = "0.14.9" diff --git a/Cargo.toml b/Cargo.toml index faf43af4..a87cc334 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ repository = "https://github.com/Plume-org/Plume" edition = "2018" [dependencies] -activitypub = "0.1.3" atom_syndication = "0.11.0" clap = "2.33" dotenv = "0.15.0" diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index 6068289f..6f830bd3 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -5,9 +5,6 @@ authors = ["Plume contributors"] edition = "2018" [dependencies] -activitypub = "0.1.1" -activitystreams-derive = "0.1.1" -activitystreams-traits = "0.1.0" array_tool = "1.0" base64 = "0.13" heck = "0.4.0" diff --git a/plume-models/Cargo.toml b/plume-models/Cargo.toml index 50749b95..83a9249f 100644 --- a/plume-models/Cargo.toml +++ b/plume-models/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Plume contributors"] edition = "2018" [dependencies] -activitypub = "0.1.1" ammonia = "3.2.0" bcrypt = "0.12.1" guid-create = "0.2" From 384474930c62515d22bfefe8304cab5300d7ff0b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 08:17:17 +0900 Subject: [PATCH 218/233] Add test for Create activity with licensed article --- plume-common/src/activity_pub/mod.rs | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 2940add7..4ba34df6 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -489,6 +489,7 @@ impl ToAsUri for OneOrMany { #[cfg(test)] mod tests { use super::*; + use activitystreams::activity::Create; use assert_json_diff::assert_json_eq; use serde_json::{from_str, json, to_value}; @@ -626,4 +627,57 @@ mod tests { assert_eq!(to_value(value).unwrap(), expected); } + + #[test] + fn de_create_with_licensed_article() { + let value: Create = from_str( + r#" + { + "id": "https://plu.me/~/Blog/my-article", + "type": "Create", + "actor": "https://plu.me/@/Admin", + "to": "https://www.w3.org/ns/activitystreams#Public", + "object": { + "type": "Article", + "id": "https://plu.me/~/Blog/my-article", + "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], + "content": "Hello.", + "name": "My Article", + "summary": "Bye.", + "source": { + "content": "Hello.", + "mediaType": "text/markdown" + }, + "published": "2014-12-12T12:12:12Z", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "license": "CC-0" + } + } + "#, + ) + .unwrap(); + let expected = json!({ + "id": "https://plu.me/~/Blog/my-article", + "type": "Create", + "actor": "https://plu.me/@/Admin", + "to": "https://www.w3.org/ns/activitystreams#Public", + "object": { + "type": "Article", + "id": "https://plu.me/~/Blog/my-article", + "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], + "content": "Hello.", + "name": "My Article", + "summary": "Bye.", + "source": { + "content": "Hello.", + "mediaType": "text/markdown" + }, + "published": "2014-12-12T12:12:12Z", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "license": "CC-0" + } + }); + + assert_eq!(to_value(value).unwrap(), expected); + } } From 19d30c12d15ed68f234c9c1df06ab03b2ce37367 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 10:04:22 +0900 Subject: [PATCH 219/233] Parse source property properly --- plume-common/src/activity_pub/mod.rs | 50 +++++++++++--------------- plume-models/src/posts.rs | 50 ++++++++++++++++++-------- plume-models/src/remote_fetch_actor.rs | 14 ++++---- 3 files changed, 62 insertions(+), 52 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 4ba34df6..a939ae35 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -452,7 +452,7 @@ where } } -pub type LicensedArticle = Ext2, Licensed, SourceProperty>; +pub type LicensedArticle = Ext1, Licensed>; pub trait ToAsString { fn to_as_string(&self) -> Option; @@ -489,7 +489,10 @@ impl ToAsUri for OneOrMany { #[cfg(test)] mod tests { use super::*; - use activitystreams::activity::Create; + use activitystreams::{ + activity::{ActorAndObjectRef, Create}, + object::kind::ArticleType, + }; use assert_json_diff::assert_json_eq; use serde_json::{from_str, json, to_value}; @@ -569,20 +572,10 @@ mod tests { Licensed { license: Some("CC-0".into()), }, - SourceProperty { - source: Source { - content: "content".into(), - media_type: "text/plain".into(), - }, - }, ); let expected = json!({ "type": "Article", "license": "CC-0", - "source": { - "content": "content", - "mediaType": "text/plain" - } }); assert_json_eq!(to_value(licensed_article).unwrap(), expected); } @@ -630,7 +623,7 @@ mod tests { #[test] fn de_create_with_licensed_article() { - let value: Create = from_str( + let create: Create = from_str( r#" { "id": "https://plu.me/~/Blog/my-article", @@ -656,26 +649,23 @@ mod tests { "#, ) .unwrap(); + let base = create.object_field_ref().as_single_base().unwrap(); + let any_base = AnyBase::from_base(base.clone()); + let value = any_base.extend::().unwrap(); let expected = json!({ + "type": "Article", "id": "https://plu.me/~/Blog/my-article", - "type": "Create", - "actor": "https://plu.me/@/Admin", - "to": "https://www.w3.org/ns/activitystreams#Public", - "object": { - "type": "Article", - "id": "https://plu.me/~/Blog/my-article", - "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], + "attributedTo": ["https://plu.me/@/Admin", "https://plu.me/~/Blog"], + "content": "Hello.", + "name": "My Article", + "summary": "Bye.", + "source": { "content": "Hello.", - "name": "My Article", - "summary": "Bye.", - "source": { - "content": "Hello.", - "mediaType": "text/markdown" - }, - "published": "2014-12-12T12:12:12Z", - "to": ["https://www.w3.org/ns/activitystreams#Public"], - "license": "CC-0" - } + "mediaType": "text/markdown" + }, + "published": "2014-12-12T12:12:12Z", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "license": "CC-0" }); assert_eq!(to_value(value).unwrap(), expected); diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 58a203f7..00291227 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -8,7 +8,7 @@ use activitystreams::{ base::{AnyBase, Base}, iri_string::types::IriString, link::{self, kind::MentionType}, - object::{kind::ImageType, ApObject, Article, AsApObject, Image, Tombstone}, + object::{kind::ImageType, ApObject, Article, AsApObject, Image, ObjectExt, Tombstone}, prelude::*, time::OffsetDateTime, }; @@ -19,8 +19,8 @@ use plume_common::{ activity_pub::{ inbox::{AsActor, AsObject, FromId}, sign::Signer, - Hashtag, HashtagType, Id, IntoId, Licensed, LicensedArticle, Source, SourceProperty, - ToAsString, ToAsUri, PUBLIC_VISIBILITY, + Hashtag, HashtagType, Id, IntoId, Licensed, LicensedArticle, ToAsString, ToAsUri, + PUBLIC_VISIBILITY, }, utils::{iri_percent_encode_seg, md_to_html}, }; @@ -367,12 +367,13 @@ impl Post { authors.push(self.get_blog(conn)?.ap_url.parse::()?); // add the blog URL here too article.set_many_attributed_tos(authors); article.set_content(self.content.get().clone()); - let source = SourceProperty { - source: Source { - content: self.source.clone(), - media_type: String::from("text/markdown"), - }, - }; + let source = AnyBase::from_arbitrary_json(serde_json::json!({ + "source": { + "content": self.source, + "mediaType": "text/markdown", + } + }))?; + article.set_source(source); article.set_published( OffsetDateTime::from_unix_timestamp_nanos(self.creation_date.timestamp_nanos().into()) .expect("OffsetDateTime"), @@ -412,7 +413,7 @@ impl Post { let license = Licensed { license: Some(self.license.clone()), }; - Ok(LicensedArticle::new(article, license, source)) + Ok(LicensedArticle::new(article, license)) } pub fn create_activity(&self, conn: &Connection) -> Result { @@ -626,7 +627,6 @@ impl FromId for Post { fn from_activity(conn: &DbConn, article: LicensedArticle) -> Result { let license = article.ext_one.license.unwrap_or_default(); - let source = article.ext_two.source.content; let article = article.inner; let (blog, authors) = article @@ -674,6 +674,18 @@ impl FromId for Post { .url() .and_then(|url| url.to_as_uri().or(id)) .ok_or(Error::MissingApProperty)?; + let source = article + .source() + .and_then(|s| { + serde_json::to_value(s).ok().and_then(|obj| { + if !obj.is_object() { + return None; + } + obj.get("content") + .and_then(|content| content.as_str().map(|c| c.to_string())) + }) + }) + .unwrap_or_default(); let post = Post::from_db(conn, &ap_url) .and_then(|mut post| { let mut updated = false; @@ -711,7 +723,7 @@ impl FromId for Post { updated = true; } if post.source != source { - post.source = source.clone(); // FIXME: Don't clone + post.source = source.clone(); updated = true; } if post.cover_id != cover { @@ -874,7 +886,18 @@ impl FromId for PostUpdate { .content() .and_then(|content| content.to_as_string()), cover: None, - source: None, + source: updated + .source() + .and_then(|s| { + serde_json::to_value(s).ok().and_then(|obj| { + if !obj.is_object() { + return None; + } + obj.get("content") + .and_then(|content| content.as_str().map(|c| c.to_string())) + }) + }) + .map(|s| s.to_string()), license: None, tags: updated .tag() @@ -891,7 +914,6 @@ impl FromId for PostUpdate { }) .and_then(|m| m.map(|m| m.id)) }); - post_update.source = Some(updated.ext_two.source.content); post_update.license = updated.ext_one.license; Ok(post_update) diff --git a/plume-models/src/remote_fetch_actor.rs b/plume-models/src/remote_fetch_actor.rs index 03f1dd76..e45a0e46 100644 --- a/plume-models/src/remote_fetch_actor.rs +++ b/plume-models/src/remote_fetch_actor.rs @@ -72,18 +72,16 @@ fn fetch_and_cache_articles(user: &Arc, conn: &DbConn) { match create_acts { Ok(create_acts) => { for create_act in create_acts { - match create_act - .object_field_ref() - .as_single_base() - .and_then(|base| { - let any_base = AnyBase::from_base(base.clone()); // FIXME: Don't clone() - any_base.extend::().ok() - }) { - Some(Some(article)) => { + match create_act.object_field_ref().as_single_base().map(|base| { + let any_base = AnyBase::from_base(base.clone()); // FIXME: Don't clone() + any_base.extend::() + }) { + Some(Ok(Some(article))) => { Post::from_activity(conn, article) .expect("Article from remote user couldn't be saved"); info!("Fetched article from remote user"); } + Some(Err(e)) => warn!("Error while fetching articles in background: {:?}", e), _ => warn!("Error while fetching articles in background"), } } From 1e0d1fb97afd71f0c3c57571233ff9b177e2bc9d Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 10:16:57 +0900 Subject: [PATCH 220/233] Add test for CustomGroup --- plume-common/src/activity_pub/mod.rs | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index a939ae35..e79751c3 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -564,6 +564,40 @@ mod tests { assert_eq!(to_value(person).unwrap(), expected); } + #[test] + fn de_custom_group() { + let group = CustomGroup::new( + ApActor::new("https://example.com/inbox".parse().unwrap(), Group::new()), + ApSignature { + public_key: PublicKey { + id: "https://example.com/pubkey".parse().unwrap(), + owner: "https://example.com/owner".parse().unwrap(), + public_key_pem: "pubKeyPem".into(), + }, + }, + SourceProperty { + source: Source { + content: String::from("This is a *custom* group."), + media_type: String::from("text/markdown"), + }, + }, + ); + let expected = json!({ + "inbox": "https://example.com/inbox", + "type": "Group", + "publicKey": { + "id": "https://example.com/pubkey", + "owner": "https://example.com/owner", + "publicKeyPem": "pubKeyPem" + }, + "source": { + "content": "This is a *custom* group.", + "mediaType": "text/markdown" + } + }); + assert_eq!(to_value(group).unwrap(), expected); + } + #[test] fn se_licensed_article() { let object = ApObject::new(Article::new()); From 1f62bf27f89ce8db7582e5f06fcf10b1e085d635 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 10:47:21 +0900 Subject: [PATCH 221/233] Fix nest of source property for Post --- plume-models/src/posts.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 00291227..9225fdc9 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -368,10 +368,8 @@ impl Post { article.set_many_attributed_tos(authors); article.set_content(self.content.get().clone()); let source = AnyBase::from_arbitrary_json(serde_json::json!({ - "source": { - "content": self.source, - "mediaType": "text/markdown", - } + "content": self.source, + "mediaType": "text/markdown", }))?; article.set_source(source); article.set_published( From b04edfa05ebdf6d7471347507b3bb2a12cde79de Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 10:53:16 +0900 Subject: [PATCH 222/233] Follow clippy --- plume-models/src/posts.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 9225fdc9..ef86ca97 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -884,18 +884,15 @@ impl FromId for PostUpdate { .content() .and_then(|content| content.to_as_string()), cover: None, - source: updated - .source() - .and_then(|s| { - serde_json::to_value(s).ok().and_then(|obj| { - if !obj.is_object() { - return None; - } - obj.get("content") - .and_then(|content| content.as_str().map(|c| c.to_string())) - }) + source: updated.source().and_then(|s| { + serde_json::to_value(s).ok().and_then(|obj| { + if !obj.is_object() { + return None; + } + obj.get("content") + .and_then(|content| content.as_str().map(|c| c.to_string())) }) - .map(|s| s.to_string()), + }), license: None, tags: updated .tag() From 0685c59bf314272b8794ce4b5a000a6bd3891c28 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 12:18:52 +0900 Subject: [PATCH 223/233] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18552e09..7836663d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Changed - Bump Rust to nightly 2022-01-26 (#1015) +- Migrate ActivityPub-related crates from activitypub 0.1 to activitystreams 0.7 ### Fixed From 0fc73727818c80a54bb5ad81bd5ed5f62836d2d7 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 12:34:56 +0900 Subject: [PATCH 224/233] Restore order of decl of boundary of broadcast() --- plume-common/src/activity_pub/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index e79751c3..eb906c5c 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -119,7 +119,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for ApRequest { } } -pub fn broadcast(sender: &S, act: A, to: Vec, proxy: Option) +pub fn broadcast(sender: &S, act: A, to: Vec, proxy: Option) where S: sign::Signer, A: Activity + serde::Serialize, From 03ba77a5777459bd5122f097804745083b2a4d38 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 12:36:31 +0900 Subject: [PATCH 225/233] Restore filter --- plume-common/src/activity_pub/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index eb906c5c..1cc2633c 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -127,6 +127,7 @@ where { let boxes = to .into_iter() + .filter(|u| !u.is_local()) .map(|u| { u.get_shared_inbox_url() .unwrap_or_else(|| u.get_inbox_url()) From f5906cacf3a66d5f513cf2391514a609d8aeb00c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 3 May 2022 22:25:43 +0900 Subject: [PATCH 226/233] Restore missing logic for Media --- plume-models/src/medias.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index 0db6b2ab..05a5278c 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -245,6 +245,10 @@ impl Media { media.is_remote = false; updated = true; } + if media.remote_url.is_some() { + media.remote_url = None; + updated = true; + } if media.sensitive != sensitive { media.sensitive = sensitive; updated = true; From 9e5f9255d10f814e9abac581c7a9f8a338a5e83c Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 5 May 2022 03:34:11 +0900 Subject: [PATCH 227/233] Add tokio to plume-common's dependencies --- plume-common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml index 795cec9e..847e2d57 100644 --- a/plume-common/Cargo.toml +++ b/plume-common/Cargo.toml @@ -24,6 +24,7 @@ regex-syntax = { version = "0.6.17", default-features = false, features = ["unic tracing = "0.1.34" askama_escape = "0.10.3" url = "2.2.2" +tokio = { version = "1.18.1", features = ["full"] } [dependencies.chrono] features = ["serde"] From 9016995d920c441304c35c1915f8655114f4dfc6 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 5 May 2022 04:33:52 +0900 Subject: [PATCH 228/233] Install tokio --- Cargo.lock | 142 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7838d43..5ff3c77d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,9 +267,9 @@ checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" @@ -779,7 +779,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "cfg-if 0.1.10", "crossbeam-utils 0.7.2", "lazy_static", @@ -828,7 +828,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "cfg-if 0.1.10", "lazy_static", ] @@ -1678,7 +1678,7 @@ dependencies = [ "http 0.2.6", "indexmap", "slab", - "tokio 1.17.0", + "tokio 1.18.1", "tokio-util 0.6.9", "tracing", ] @@ -1936,7 +1936,7 @@ dependencies = [ "itoa 1.0.1", "pin-project-lite 0.2.8", "socket2 0.4.4", - "tokio 1.17.0", + "tokio 1.18.1", "tower-service", "tracing", "want 0.3.0", @@ -1977,7 +1977,7 @@ dependencies = [ "bytes 1.1.0", "hyper 0.14.18", "native-tls", - "tokio 1.17.0", + "tokio 1.18.1", "tokio-native-tls", ] @@ -2021,7 +2021,7 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "hashbrown 0.11.2", ] @@ -2173,7 +2173,7 @@ dependencies = [ "nom 2.2.1", "percent-encoding 2.1.0", "thiserror", - "tokio 1.17.0", + "tokio 1.18.1", "tokio-native-tls", "tokio-stream", "tokio-util 0.7.0", @@ -2366,10 +2366,11 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] @@ -2466,7 +2467,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2475,7 +2476,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2537,7 +2538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2561,14 +2562,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ "libc", "log 0.4.14", "miow 0.3.7", "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", "winapi 0.3.9", ] @@ -2802,7 +2804,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-integer", "num-traits 0.2.14", ] @@ -2813,7 +2815,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-traits 0.2.14", ] @@ -2823,7 +2825,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "num-integer", "num-traits 0.2.14", ] @@ -2843,7 +2845,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", ] [[package]] @@ -2922,7 +2924,7 @@ version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "cc", "libc", "pkg-config", @@ -2965,10 +2967,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.5", + "lock_api 0.4.7", "parking_lot_core 0.8.5", ] +[[package]] +name = "parking_lot" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +dependencies = [ + "lock_api 0.4.7", + "parking_lot_core 0.9.3", +] + [[package]] name = "parking_lot_core" version = "0.6.2" @@ -2998,6 +3010,19 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.10", + "smallvec 1.8.0", + "windows-sys", +] + [[package]] name = "pear" version = "0.1.4" @@ -3228,6 +3253,7 @@ dependencies = [ "serde_json", "shrinkwraprs", "syntect", + "tokio 1.18.1", "tracing", "url 2.2.2", ] @@ -3713,7 +3739,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ - "autocfg 1.0.1", + "autocfg 1.1.0", "crossbeam-deque 0.8.1", "either 1.6.1", "rayon-core", @@ -3884,7 +3910,7 @@ dependencies = [ "serde 1.0.137", "serde_json", "serde_urlencoded 0.7.1", - "tokio 1.17.0", + "tokio 1.18.1", "tokio-native-tls", "tokio-socks", "url 2.2.2", @@ -4840,16 +4866,19 @@ dependencies = [ [[package]] name = "tokio" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc" dependencies = [ "bytes 1.1.0", "libc", "memchr", - "mio 0.8.0", + "mio 0.8.2", "num_cpus", + "once_cell", + "parking_lot 0.12.0", "pin-project-lite 0.2.8", + "signal-hook-registry", "socket2 0.4.4", "tokio-macros 1.7.0", "winapi 0.3.9", @@ -4926,7 +4955,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", - "tokio 1.17.0", + "tokio 1.18.1", ] [[package]] @@ -4957,7 +4986,7 @@ dependencies = [ "either 1.6.1", "futures-util", "thiserror", - "tokio 1.17.0", + "tokio 1.18.1", ] [[package]] @@ -4968,7 +4997,7 @@ checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" dependencies = [ "futures-core", "pin-project-lite 0.2.8", - "tokio 1.17.0", + "tokio 1.18.1", ] [[package]] @@ -5059,7 +5088,7 @@ dependencies = [ "futures-sink", "log 0.4.14", "pin-project-lite 0.2.8", - "tokio 1.17.0", + "tokio 1.18.1", ] [[package]] @@ -5073,7 +5102,7 @@ dependencies = [ "futures-sink", "log 0.4.14", "pin-project-lite 0.2.8", - "tokio 1.17.0", + "tokio 1.18.1", ] [[package]] @@ -5454,6 +5483,12 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.80" @@ -5596,6 +5631,49 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "winreg" version = "0.6.2" From ce4b216722c1917a5e98c8ff55962c7c06dae62a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 5 May 2022 04:34:04 +0900 Subject: [PATCH 229/233] Broadcast asynchronously --- plume-common/src/activity_pub/mod.rs | 94 +++++++++++++++++----------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 9b85a4c0..69d40cd5 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -1,12 +1,13 @@ use activitypub::{Activity, Link, Object}; use array_tool::vec::Uniq; -use reqwest::{blocking::ClientBuilder, header::HeaderValue, Url}; +use reqwest::{header::HeaderValue, ClientBuilder, Url}; use rocket::{ http::Status, request::{FromRequest, Request}, response::{Responder, Response}, Outcome, }; +use tokio::{runtime, sync::mpsc}; use tracing::{debug, warn}; use self::sign::Signable; @@ -139,46 +140,63 @@ where .connect_timeout(std::time::Duration::from_secs(5)) .build() .expect("Can't build client"); - for inbox in boxes { - let body = signed.to_string(); - let mut headers = request::headers(); - let url = Url::parse(&inbox); - if url.is_err() { - warn!("Inbox is invalid URL: {:?}", &inbox); - continue; - } - let url = url.unwrap(); - if !url.has_host() { - warn!("Inbox doesn't have host: {:?}", &inbox); - continue; - }; - let host_header_value = HeaderValue::from_str(url.host_str().expect("Unreachable")); - if host_header_value.is_err() { - warn!("Header value is invalid: {:?}", url.host_str()); - continue; - } - headers.insert("Host", host_header_value.unwrap()); - headers.insert("Digest", request::Digest::digest(&body)); - let _ = client - .post(&inbox) - .headers(headers.clone()) - .header( + let rt = runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Error while initializing tokio runtime for federation"); + rt.block_on(async { + let (tx, mut rx) = mpsc::channel(32); + for inbox in boxes { + let body = signed.to_string(); + let mut headers = request::headers(); + let url = Url::parse(&inbox); + if url.is_err() { + warn!("Inbox is invalid URL: {:?}", &inbox); + continue; + } + let url = url.unwrap(); + if !url.has_host() { + warn!("Inbox doesn't have host: {:?}", &inbox); + continue; + }; + let host_header_value = HeaderValue::from_str(url.host_str().expect("Unreachable")); + if host_header_value.is_err() { + warn!("Header value is invalid: {:?}", url.host_str()); + continue; + } + headers.insert("Host", host_header_value.unwrap()); + headers.insert("Digest", request::Digest::digest(&body)); + headers.insert( "Signature", request::signature(sender, &headers, ("post", url.path(), url.query())) .expect("activity_pub::broadcast: request signature error"), - ) - .body(body) - .send() - .map(move |r| { - if r.status().is_success() { - debug!("Successfully sent activity to inbox ({})", &inbox); - } else { - warn!("Error while sending to inbox ({} {:?})", &inbox, &r) - } - debug!("Response: \"{:?}\"\n", r); - }) - .map_err(|e| warn!("Error while sending to inbox ({:?})", e)); - } + ); + let client = client.clone(); + let tx = tx.clone(); + rt.spawn(async move { + let _ = tx.send( + client + .post(&inbox) + .headers(headers.clone()) + .body(body) + .send() + .await, + ); + }); + } + while let Some(request) = rx.recv().await { + let _ = request + .map(move |r| { + if r.status().is_success() { + debug!("Successfully sent activity to inbox ({})", &r.url()); + } else { + warn!("Error while sending to inbox ({} {:?})", &r.url(), &r) + } + debug!("Response: \"{:?}\"\n", r); + }) + .map_err(|e| warn!("Error while sending to inbox ({:?})", e)); + } + }); } #[derive(Shrinkwrap, Clone, Serialize, Deserialize)] From f22c4d5c787dfcafe0b65c2794108176039c9429 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 5 May 2022 04:51:42 +0900 Subject: [PATCH 230/233] Await in consumer --- plume-common/src/activity_pub/mod.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 69d40cd5..07a1b908 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -173,26 +173,28 @@ where ); let client = client.clone(); let tx = tx.clone(); - rt.spawn(async move { - let _ = tx.send( + let _ = tx.send( + rt.spawn( client .post(&inbox) .headers(headers.clone()) .body(body) - .send() - .await, - ); - }); + .send(), + ), + ); } while let Some(request) = rx.recv().await { let _ = request + .await .map(move |r| { - if r.status().is_success() { - debug!("Successfully sent activity to inbox ({})", &r.url()); - } else { - warn!("Error while sending to inbox ({} {:?})", &r.url(), &r) - } - debug!("Response: \"{:?}\"\n", r); + r.map(|r| { + if r.status().is_success() { + debug!("Successfully sent activity to inbox ({})", &r.url()); + } else { + warn!("Error while sending to inbox ({} {:?})", &r.url(), &r) + } + debug!("Response: \"{:?}\"\n", r); + }) }) .map_err(|e| warn!("Error while sending to inbox ({:?})", e)); } From 4e833c2061743eccb8a11b9f2713dd0f0e2e4a77 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 5 May 2022 13:14:11 +0900 Subject: [PATCH 231/233] Follow clippy --- plume-common/src/activity_pub/mod.rs | 2 +- plume-models/src/users.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 2a076f62..bb7ea792 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -18,7 +18,7 @@ use rocket::{ response::{Responder, Response}, Outcome, }; -use tokio::{runtime, sync::mpsc}; +use tokio::runtime; use tracing::{debug, warn}; use self::sign::Signable; diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 4c572b3b..b33f9bc1 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -517,7 +517,7 @@ impl User { &self, url: &str, ) -> Result<(Vec, Option)> { - let mut res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; + let res = get(url, Self::get_sender(), CONFIG.proxy().cloned())?; let text = &res.text()?; let json: serde_json::Value = serde_json::from_str(text)?; let items = json["items"] @@ -532,7 +532,7 @@ impl User { } pub fn fetch_outbox(&self) -> Result> { - let mut res = get( + let res = get( &self.outbox_url[..], Self::get_sender(), CONFIG.proxy().cloned(), From 9fbafd8e79c7527b1821467a89ac17ce631b613b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Fri, 6 May 2022 11:38:04 +0900 Subject: [PATCH 232/233] Fix Follow object in accepting follow --- plume-models/src/follows.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 2a334767..ee7e4587 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -161,9 +161,7 @@ impl AsObject for User { fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result { // Mastodon (at least) requires the full Follow object when accepting it, // so we rebuilt it here - let mut follow = - FollowAct::new(id.parse::()?, actor.ap_url.parse::()?); - follow.set_id(id.parse::()?); + let follow = FollowAct::new(actor.ap_url.parse::()?, id.parse::()?); Follow::accept_follow(conn, &actor, &self, follow, actor.id, self.id) } } From 96860be1beddb7bbe8457328bca4f49f0b0f35f5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 8 May 2022 18:00:42 +0900 Subject: [PATCH 233/233] Fix Follow::accept_follow() --- plume-models/src/follows.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index ee7e4587..c74b90a1 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -98,7 +98,8 @@ impl Follow { follower_id: from_id, following_id: target_id, ap_url: follow - .id_unchecked() + .object_field_ref() + .as_single_id() .ok_or(Error::MissingApProperty)? .to_string(), },