Compare commits

...

3 Commits

Author SHA1 Message Date
Astro 42728d0efb buzzback: init 2023-10-12 20:11:21 +02:00
Astro 9378cfc0b3 cargo update 2023-10-10 19:40:23 +02:00
Astro c9506651ed flake.lock: Update
Flake lock file updates:

• Updated input 'fenix':
    'github:nix-community/fenix/9ccae1754eec0341b640d5705302ac0923d22875' (2023-10-01)
  → 'github:nix-community/fenix/638fc95a2a3d01b372c76f71cbb6d73c63909d6e' (2023-10-10)
• Updated input 'fenix/rust-analyzer-src':
    'github:rust-lang/rust-analyzer/0840038f02daec6ba3238f05d8caa037d28701a0' (2023-09-30)
  → 'github:rust-lang/rust-analyzer/aaa1e8e1b82d742b876d164a30dda02f318ce809' (2023-10-09)
• Updated input 'nixpkgs':
    'path:/nix/store/z5r8imp4q5wjfl58d064rwm20cym02c0-source?lastModified=1693844670&narHash=sha256-t69F2nBB8DNQUWHD809oJZJVE%2B23XBrth4QZuVd6IE0%3D&rev=3c15feef7770eb5500a4b8792623e2d6f598c9c1' (2023-09-04)
  → 'path:/nix/store/h93pa4qif40f0hjwrs155ihb3lpf36m7-source?lastModified=1696375444&narHash=sha256-Sv0ICt/pXfpnFhTGYTsX6lUr1SljnuXWejYTI2ZqHa4%3D&rev=81e8f48ebdecf07aab321182011b067aafc78896' (2023-10-03)
2023-10-10 19:34:19 +02:00
12 changed files with 572 additions and 99 deletions

236
Cargo.lock generated
View File

@ -39,9 +39,9 @@ dependencies = [
[[package]]
name = "aho-corasick"
version = "1.1.1"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
@ -151,7 +151,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -253,6 +253,18 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5"
[[package]]
name = "base64"
version = "0.21.4"
@ -316,11 +328,31 @@ version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "buzzback"
version = "0.1.0"
dependencies = [
"http",
"http_digest_headers",
"httpdate",
"reqwest",
"serde",
"serde_json",
"serde_yaml",
"sigh",
"thiserror",
"tokio",
"tokio-postgres",
"tracing",
"tracing-subscriber",
"urlencoding 2.1.3",
]
[[package]]
name = "byteorder"
version = "1.4.3"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
@ -391,7 +423,7 @@ dependencies = [
"serde_yaml",
"tokio",
"tracing",
"urlencoding",
"urlencoding 1.3.3",
]
[[package]]
@ -413,7 +445,7 @@ dependencies = [
"tokio",
"tokio-uring",
"tracing",
"urlencoding",
"urlencoding 1.3.3",
]
[[package]]
@ -582,14 +614,14 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
[[package]]
name = "enum-as-inner"
version = "0.5.1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116"
checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.38",
]
[[package]]
@ -600,25 +632,14 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480"
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "eventsource-stream"
version = "0.2.3"
@ -691,7 +712,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -771,7 +792,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -925,6 +946,18 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f"
[[package]]
name = "http_digest_headers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7db39af769c6cb000b7ea765bd5eedcc812d3ec00f3ea50e073c19e00a75916d"
dependencies = [
"anyhow",
"base64 0.13.1",
"openssl",
"thiserror",
]
[[package]]
name = "httparse"
version = "1.8.0"
@ -1003,17 +1036,6 @@ dependencies = [
"cc",
]
[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "idna"
version = "0.4.0"
@ -1117,9 +1139,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.148"
version = "0.2.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
[[package]]
name = "libmimalloc-sys"
@ -1150,9 +1172,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.4.8"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
[[package]]
name = "lock_api"
@ -1203,12 +1225,6 @@ dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "matches"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]]
name = "matchit"
version = "0.5.0"
@ -1402,9 +1418,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
@ -1457,7 +1473,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -1557,7 +1573,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -1599,7 +1615,7 @@ version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520"
dependencies = [
"base64",
"base64 0.21.4",
"byteorder",
"bytes",
"fallible-iterator",
@ -1630,9 +1646,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.67"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
@ -1750,14 +1766,14 @@ dependencies = [
[[package]]
name = "regex"
version = "1.9.6"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87"
dependencies = [
"aho-corasick 1.1.1",
"aho-corasick 1.1.2",
"memchr",
"regex-automata 0.3.9",
"regex-syntax 0.7.5",
"regex-automata 0.4.1",
"regex-syntax 0.8.0",
]
[[package]]
@ -1771,13 +1787,13 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.3.9"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b"
dependencies = [
"aho-corasick 1.1.1",
"aho-corasick 1.1.2",
"memchr",
"regex-syntax 0.7.5",
"regex-syntax 0.8.0",
]
[[package]]
@ -1788,18 +1804,18 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.7.5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d"
[[package]]
name = "reqwest"
version = "0.11.20"
version = "0.11.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
dependencies = [
"async-compression",
"base64",
"base64 0.21.4",
"bytes",
"encoding_rs",
"futures-core",
@ -1820,6 +1836,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
"system-configuration",
"tokio",
"tokio-native-tls",
"tokio-util",
@ -1851,9 +1868,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
version = "0.38.15"
version = "0.38.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531"
checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c"
dependencies = [
"bitflags 2.4.0",
"errno",
@ -1929,7 +1946,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -1987,13 +2004,26 @@ dependencies = [
[[package]]
name = "sharded-slab"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "sigh"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17a67f3294aadf0022646d41c33b888d79db23670e4c34b1bc007c6f901a3b77"
dependencies = [
"base64 0.20.0",
"http",
"nom",
"openssl",
"thiserror",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
@ -2080,9 +2110,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.37"
version = "2.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
dependencies = [
"proc-macro2",
"quote",
@ -2095,6 +2125,27 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "systemd"
version = "0.10.0"
@ -2156,7 +2207,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -2186,9 +2237,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.32.0"
version = "1.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
dependencies = [
"backtrace",
"bytes",
@ -2212,7 +2263,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -2362,7 +2413,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
]
[[package]]
@ -2406,9 +2457,9 @@ dependencies = [
[[package]]
name = "trust-dns-proto"
version = "0.22.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26"
checksum = "0dc775440033cb114085f6f2437682b194fa7546466024b1037e82a48a052a69"
dependencies = [
"async-trait",
"cfg-if",
@ -2417,9 +2468,9 @@ dependencies = [
"futures-channel",
"futures-io",
"futures-util",
"idna 0.2.3",
"idna",
"ipnet",
"lazy_static",
"once_cell",
"rand",
"smallvec",
"thiserror",
@ -2431,16 +2482,17 @@ dependencies = [
[[package]]
name = "trust-dns-resolver"
version = "0.22.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe"
checksum = "2dff7aed33ef3e8bf2c9966fccdfed93f93d46f432282ea875cd66faabc6ef2f"
dependencies = [
"cfg-if",
"futures-util",
"ipconfig",
"lazy_static",
"lru-cache",
"once_cell",
"parking_lot",
"rand",
"resolv-conf",
"smallvec",
"thiserror",
@ -2504,7 +2556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
dependencies = [
"form_urlencoded",
"idna 0.4.0",
"idna",
"percent-encoding",
]
@ -2514,6 +2566,12 @@ version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb"
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf8-cstr"
version = "0.1.6"
@ -2580,7 +2638,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
"wasm-bindgen-shared",
]
@ -2614,7 +2672,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
"syn 2.0.38",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]

View File

@ -5,6 +5,7 @@ members = [
"butcher",
"gatherer",
"smokestack",
"buzzback",
]
resolver = "2"

21
buzzback/Cargo.toml Normal file
View File

@ -0,0 +1,21 @@
[package]
name = "buzzback"
description = "Follows back"
version = "0.1.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["full", "time"] }
tracing = "*"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
serde = { version = "1", features = ["serde_derive"] }
serde_json = "1"
serde_yaml = "0.9"
reqwest = { version = "0.11", features = ["json", "stream"] }
sigh = "1.0"
http_digest_headers = { version="0.1.0", default-features = false, features = ["use_openssl"] }
thiserror = "1"
http = "0.2"
tokio-postgres = "0.7"
urlencoding = "2"
httpdate = "1"

45
buzzback/config.yaml Normal file
View File

@ -0,0 +1,45 @@
# external https hostname
hostname: relay.fedi.buzz
# ActivityPub signing keypair
priv_key_file: private-key.pem
#pub_key_file: public-key.pem
# PostgreSQL
db: "host=localhost user=relay password=xyz dbname=buzzrelay"
default_actor: https://relay.fedi.buzz/tag/FediBuzz
relays:
- https://relay.c.im/inbox
- https://relay.beckmeyer.us/inbox
- https://relay.froth.zone/inbox
- https://relay.intahnet.co.uk/inbox
- https://relay.infosec.exchange/inbox
- https://relay.toot.io/inbox
- https://bigrelay.social/inbox
- https://relay.toot.yukimochi.jp/inbox
- https://relay.an.exchange/inbox
- https://relay.fedinet.social/inbox
- https://relay.intahnet.co.uk/inbox
- https://en.relay.friendi.ca/inbox
- https://relay.101010.pl/inbox
- https://relay.chocoflan.net/inbox
- https://relay.dresden.network/inbox
- https://mastodon-relay.moew.science/inbox
- https://relay.beckmeyer.us/inbox
- https://relay.fedi.agency/inbox
- https://relay.fedinet.social/inbox
- https://relay.flm9.me/inbox
- https://relay.froth.zone/inbox
- https://relay.homunyan.com/inbox
- https://relay.intahnet.co.uk/inbox
- https://relay.libranet.de/inbox
- https://relay.masto.la/inbox
- https://relay.minecloud.ro/inbox
- https://relay.mistli.net/inbox
- https://relay.pissdichal.de/inbox
- https://relay.toot.yukimochi.jp/inbox
- https://relay.uggs.io/inbox
- https://relay.wagnersnetz.de/inbox
- https://relay.wig.gl/inbox
- https://relay.dog/inbox
- https://relay.darmstadt.social/inbox
- https://relay.douzepoints.social/inbox

View File

@ -0,0 +1,48 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Actor {
#[serde(rename = "@context")]
pub jsonld_context: serde_json::Value,
#[serde(rename = "type")]
pub actor_type: String,
pub id: String,
pub name: Option<String>,
pub icon: Option<Media>,
pub inbox: String,
pub outbox: String,
#[serde(rename = "publicKey")]
pub public_key: ActorPublicKey,
#[serde(rename = "preferredUsername")]
pub preferred_username: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ActorPublicKey {
pub id: String,
pub owner: Option<String>,
#[serde(rename = "publicKeyPem")]
pub pem: String,
}
/// `ActivityPub` "activity"
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Action<O> {
#[serde(rename = "@context")]
pub jsonld_context: serde_json::Value,
#[serde(rename = "type")]
pub action_type: String,
pub id: String,
pub actor: String,
pub to: Option<serde_json::Value>,
pub object: Option<O>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Media {
#[serde(rename = "type")]
pub media_type: String,
#[serde(rename = "mediaType")]
pub content_type: String,
pub url: String,
}

35
buzzback/src/config.rs Normal file
View File

@ -0,0 +1,35 @@
use serde::Deserialize;
use sigh::{PrivateKey, Key};
#[derive(Deserialize)]
pub struct Config {
pub db: String,
pub hostname: String,
priv_key_file: String,
// pub_key_file: String,
pub default_actor: String,
pub relays: Vec<String>,
}
impl Config {
pub fn load(config_file: &str) -> Config {
let data = std::fs::read_to_string(config_file)
.expect("read config");
serde_yaml::from_str(&data)
.expect("parse config")
}
pub fn priv_key(&self) -> PrivateKey {
let data = std::fs::read_to_string(&self.priv_key_file)
.expect("read priv_key_file");
PrivateKey::from_pem(data.as_bytes())
.expect("priv_key")
}
// pub fn pub_key(&self) -> PublicKey {
// let data = std::fs::read_to_string(&self.pub_key_file)
// .expect("read pub_key_file");
// PublicKey::from_pem(data.as_bytes())
// .expect("pub_key")
// }
}

54
buzzback/src/db.rs Normal file
View File

@ -0,0 +1,54 @@
use std::sync::Arc;
use tokio_postgres::{Client, Error, NoTls};
#[derive(Clone, Debug)]
pub struct Follow {
/// Follower identification
pub id: String,
/// Subscribing inbox that is supposed to receive pushes
pub inbox: String,
/// Followed actor
pub actor: String,
}
#[derive(Clone)]
pub struct Database {
inner: Arc<DatabaseInner>,
}
struct DatabaseInner {
client: Client,
}
impl Database {
pub async fn connect(conn_str: &str) -> Self {
let (client, connection) = tokio_postgres::connect(conn_str, NoTls)
.await
.unwrap();
tokio::spawn(async move {
if let Err(e) = connection.await {
tracing::error!("postgresql: {}", e);
}
});
Database {
inner: Arc::new(DatabaseInner {
client,
}),
}
}
pub async fn get_instance_followers(&self) -> Result<impl Iterator<Item = Follow>, Error> {
let rows = self.inner.client.query("SELECT inbox, MIN(id), MIN(actor) FROM follows WHERE inbox LIKE '%/actor/inbox' GROUP BY inbox", &[])
.await?;
Ok(rows.into_iter()
.map(|row| Follow {
id: row.get(1),
inbox: row.get(0),
actor: row.get(2),
})
)
}
}

20
buzzback/src/digest.rs Normal file
View File

@ -0,0 +1,20 @@
use http_digest_headers::{DigestHeader, DigestMethod};
pub fn generate_header(body: &[u8]) -> Result<String, ()> {
let mut digest_header = DigestHeader::new()
.with_method(DigestMethod::SHA256, body)
.map(|h| format!("{}", h))
.map_err(|_| ())?;
// mastodon expects uppercase algo name
if digest_header.starts_with("sha-") {
digest_header.replace_range(..4, "SHA-");
}
// mastodon uses base64::alphabet::STANDARD, not base64::alphabet::URL_SAFE
digest_header.replace_range(
7..,
&digest_header[7..].replace('-', "+").replace('_', "/")
);
Ok(digest_header)
}

17
buzzback/src/error.rs Normal file
View File

@ -0,0 +1,17 @@
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("HTTP Digest generation error")]
Digest,
#[error("JSON encoding error")]
Json(#[from] serde_json::Error),
#[error("Signature error")]
Signature(#[from] sigh::Error),
#[error("HTTP request error")]
HttpReq(#[from] http::Error),
#[error("HTTP client error")]
Http(#[from] reqwest::Error),
#[error("Invalid URI")]
InvalidUri,
#[error("Error response from remote")]
Response(String),
}

117
buzzback/src/main.rs Normal file
View File

@ -0,0 +1,117 @@
use sigh::PrivateKey;
use std::{sync::Arc, time::Duration};
use std::{panic, process};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
mod error;
mod config;
mod db;
mod activitypub;
mod digest;
mod send;
async fn follow_back(
client: &reqwest::Client, hostname: &str,
priv_key: &PrivateKey,
follow: db::Follow,
) {
let follow_id = format!(
"https://{}/activity/follow/{}/{}",
hostname,
urlencoding::encode(&follow.id),
urlencoding::encode(&follow.actor),
);
let action = activitypub::Action {
jsonld_context: serde_json::Value::String("https://www.w3.org/ns/activitystreams".to_string()),
action_type: "Follow".to_string(),
id: follow_id,
to: None,
actor: follow.actor.clone(),
object: Some(&follow.id),
};
let key_id = format!("{}#key", follow.actor);
let result = send::send(
client, &follow.inbox,
&key_id, &priv_key,
&action,
).await;
match result {
Ok(()) => {
tracing::info!("Ok {}", follow.id);
}
Err(e) => {
tracing::error!("POST: {:?}", e);
}
}
}
#[tokio::main]
async fn main() {
exit_on_panic();
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
"buzzback=trace,tower_http=trace,axum=trace".into()
}),
)
.with(tracing_subscriber::fmt::layer())
.init();
let config = config::Config::load(
&std::env::args().nth(1)
.expect("Call with config.yaml")
);
let priv_key = config.priv_key();
let client = Arc::new(
reqwest::Client::builder()
.timeout(Duration::from_secs(5))
.user_agent(concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
))
.pool_max_idle_per_host(0)
.pool_idle_timeout(Some(Duration::from_secs(1)))
.build()
.unwrap()
);
// Follow relays from the static list in the config.yaml
for relay in config.relays {
let (id, inbox) =
if relay.ends_with("/inbox") {
(relay.replace("/inbox", "/actor"), relay.clone())
} else if relay.ends_with("/actor") {
(relay.clone(), relay.replace("/actor", "/inbox"))
} else {
panic!("Not sure how to deal with relay {}", relay);
};
tracing::trace!("Following {}", &id);
let follow = db::Follow {
id,
actor: config.default_actor.clone(),
inbox,
};
follow_back(&client, &config.hostname, &priv_key, follow).await;
}
let database = db::Database::connect(&config.db).await;
let instance_followers = database.get_instance_followers().await.unwrap();
// Follow back every instance that followed us
for follow in instance_followers {
tracing::trace!("Following {}", follow.id);
follow_back(&client, &config.hostname, &priv_key, follow).await;
}
}
fn exit_on_panic() {
let orig_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
// invoke the default handler and exit the process
orig_hook(panic_info);
process::exit(1);
}));
}

57
buzzback/src/send.rs Normal file
View File

@ -0,0 +1,57 @@
use std::{
sync::Arc,
time::SystemTime,
};
use http::StatusCode;
use serde::Serialize;
use sigh::{PrivateKey, SigningConfig, alg::RsaSha256};
use crate::{digest, error::Error};
pub async fn send<T: Serialize>(
client: &reqwest::Client,
uri: &str,
key_id: &str,
private_key: &PrivateKey,
body: &T,
) -> Result<(), Error> {
let body = Arc::new(
serde_json::to_vec(body)
.map_err(Error::Json)?
);
send_raw(client, uri, key_id, private_key, body).await
}
pub async fn send_raw(
client: &reqwest::Client,
uri: &str,
key_id: &str,
private_key: &PrivateKey,
body: Arc<Vec<u8>>,
) -> Result<(), Error> {
let url = reqwest::Url::parse(uri)
.map_err(|_| Error::InvalidUri)?;
let host = format!("{}", url.host().ok_or(Error::InvalidUri)?);
let digest_header = digest::generate_header(&body)
.map_err(|()| Error::Digest)?;
let mut req = http::Request::builder()
.method("POST")
.uri(uri)
.header("host", &host)
.header("content-type", "application/activity+json")
.header("date", httpdate::fmt_http_date(SystemTime::now()))
.header("digest", digest_header)
.body(body.as_ref().clone())
.map_err(Error::HttpReq)?;
SigningConfig::new(RsaSha256, private_key, key_id)
.sign(&mut req)?;
let req: reqwest::Request = req.try_into()?;
let res = client.execute(req)
.await?;
if res.status() >= StatusCode::OK && res.status() < StatusCode::MULTIPLE_CHOICES {
Ok(())
} else {
tracing::error!("send_raw {} response HTTP {}", url, res.status());
let response = res.text().await?;
Err(Error::Response(response))
}
}

View File

@ -8,11 +8,11 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1696141234,
"narHash": "sha256-0dZpggYjjmWEk+rGixiBHOHuQfLzEzNfrtjSig04s6Q=",
"lastModified": 1696918968,
"narHash": "sha256-18rAHsM9YsGp7aKKemO4gKIeWfrSyDsdJZ/mk4dQ3JI=",
"owner": "nix-community",
"repo": "fenix",
"rev": "9ccae1754eec0341b640d5705302ac0923d22875",
"rev": "638fc95a2a3d01b372c76f71cbb6d73c63909d6e",
"type": "github"
},
"original": {
@ -43,10 +43,10 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1693844670,
"narHash": "sha256-t69F2nBB8DNQUWHD809oJZJVE+23XBrth4QZuVd6IE0=",
"path": "/nix/store/z5r8imp4q5wjfl58d064rwm20cym02c0-source",
"rev": "3c15feef7770eb5500a4b8792623e2d6f598c9c1",
"lastModified": 1696375444,
"narHash": "sha256-Sv0ICt/pXfpnFhTGYTsX6lUr1SljnuXWejYTI2ZqHa4=",
"path": "/nix/store/h93pa4qif40f0hjwrs155ihb3lpf36m7-source",
"rev": "81e8f48ebdecf07aab321182011b067aafc78896",
"type": "path"
},
"original": {
@ -65,11 +65,11 @@
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1696050837,
"narHash": "sha256-2K3Aq4gjPZBDnkAMJaMA4ElE+BNbmrqtSBWtt9kPGaM=",
"lastModified": 1696840854,
"narHash": "sha256-wphOvjDSDsUN5DMe3MOhdargANIab7YE3hkh3Qv7qso=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "0840038f02daec6ba3238f05d8caa037d28701a0",
"rev": "aaa1e8e1b82d742b876d164a30dda02f318ce809",
"type": "github"
},
"original": {