NodeInfo serde, basic config support, modularization

This commit is contained in:
Natty 2023-02-26 03:31:39 +01:00
parent 2d46e81461
commit f8e86c74a7
Signed by: natty
GPG Key ID: BF6CB659ADEE60EC
16 changed files with 919 additions and 9 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
/target
.idea
.vscode
.vscode
/.env

439
Cargo.lock generated
View File

@ -75,24 +75,85 @@ dependencies = [
"tower-service",
]
[[package]]
name = "base64ct"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const-oid"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "der"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "digest"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"const-oid",
"crypto-common",
]
[[package]]
name = "dotenvy"
version = "0.15.6"
@ -153,6 +214,27 @@ dependencies = [
"pin-utils",
]
[[package]]
name = "generic-array"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "h2"
version = "0.3.15"
@ -277,11 +359,23 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "js-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin",
]
[[package]]
name = "libc"
@ -289,6 +383,12 @@ version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libm"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
[[package]]
name = "lock_api"
version = "0.4.9"
@ -317,14 +417,23 @@ dependencies = [
"dotenvy",
"hyper",
"magnetar_core",
"rand",
"ring",
"rsa",
"serde",
"serde_json",
"tokio",
"toml",
"tower",
"tower-http",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "magnetar_activity_pub"
version = "0.1.0"
[[package]]
name = "magnetar_core"
version = "0.1.0"
@ -334,6 +443,14 @@ dependencies = [
"url",
]
[[package]]
name = "magnetar_nodeinfo"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "matchers"
version = "0.1.0"
@ -373,6 +490,15 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "nom8"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
dependencies = [
"memchr",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
@ -383,6 +509,54 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand",
"smallvec",
"zeroize",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
@ -428,6 +602,15 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "pem-rfc7468"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac"
dependencies = [
"base64ct",
]
[[package]]
name = "percent-encoding"
version = "2.2.0"
@ -466,6 +649,34 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs1"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719"
dependencies = [
"der",
"pkcs8",
"spki",
"zeroize",
]
[[package]]
name = "pkcs8"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
dependencies = [
"der",
"spki",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.51"
@ -484,6 +695,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
@ -517,6 +758,41 @@ version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"web-sys",
"winapi",
]
[[package]]
name = "rsa"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b3896c9b7790b70a9aa314a30e4ae114200992a19c96cbe0ca6070edd32ab8"
dependencies = [
"byteorder",
"digest",
"num-bigint-dig",
"num-integer",
"num-iter",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"signature",
"subtle",
"zeroize",
]
[[package]]
name = "rustversion"
version = "1.0.11"
@ -575,6 +851,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -605,6 +890,16 @@ dependencies = [
"libc",
]
[[package]]
name = "signature"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d"
dependencies = [
"digest",
"rand_core",
]
[[package]]
name = "slab"
version = "0.4.7"
@ -630,6 +925,28 @@ dependencies = [
"winapi",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spki"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
dependencies = [
"base64ct",
"der",
]
[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.107"
@ -717,6 +1034,40 @@ dependencies = [
"tracing",
]
[[package]]
name = "toml"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5"
dependencies = [
"indexmap",
"nom8",
"serde",
"serde_spanned",
"toml_datetime",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -834,6 +1185,12 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicode-bidi"
version = "0.3.10"
@ -855,6 +1212,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "2.3.1"
@ -873,6 +1236,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "want"
version = "0.3.0"
@ -889,6 +1258,70 @@ 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.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
[[package]]
name = "web-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
@ -991,3 +1424,9 @@ name = "windows_x86_64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "zeroize"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"

View File

@ -8,6 +8,8 @@ edition = "2021"
[workspace]
members = [
".",
"ext_activity_pub",
"ext_nodeinfo",
"core"
]
@ -27,4 +29,11 @@ tower-http = { version = "0.3", features = ["cors", "trace"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing = "0.1"
serde = { version = "1.0", features = ["derive"] }
ring = "0.16"
rand = { version = "0.8", features = ["getrandom"] }
rsa = "0.8"
serde = { version = "1.0", features = ["derive"] }
toml = "0.7"
serde_json = "1.0"

3
config/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*
!.gitignore
!default.toml

47
config/default.toml Normal file
View File

@ -0,0 +1,47 @@
# Primary Magnetar configuration.
# The location of the config to load may be overriden with MAG_CONFIG_PATH.
# Please note options in this file take priority over environment variables.
# Container quick start:
# Technically it's not necessary to edit this file at all.
# Set the following variables:
# - MAG_C_HOST (host)
# --------------------------------[ LOGGING ]----------------------------------
# Logging can be configured using the RUST_LOG environment variable.
# See https://docs.rs/env_logger/0.10.0/env_logger/#enabling-logging
# Default: "info"
# -------------------------------[ NETWORKING ]--------------------------------
# Magnetar does not contain a TLS ingress, please use a reverse proxy like:
# - Nginx (https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
# - Caddy (https://caddyserver.com/docs/quick-starts/reverse-proxy)
# - Traefik
# [REQUIRED]
# The hostname the instance will run on.
# Environment variable: MAG_C_HOST
# networking.host = "example.com"
# [Optional]
# The IP address the application will bind to.
# Default: "::"
# Environment variable: MAG_C_BIND_ADDR
# networking.bind_addr = "::"
# [Optional]
# The port of the instance.
# Default: 4939
# Environment variable: MAG_C_PORT
# networking.port = 4939
# ----------------------------------[ DATA ]-----------------------------------
# -------------------------------[ FEDERATION ]--------------------------------

View File

@ -0,0 +1,7 @@
[package]
name = "magnetar_activity_pub"
version = "0.1.0"
edition = "2021"
[dependencies]

View File

@ -0,0 +1 @@

8
ext_nodeinfo/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "magnetar_nodeinfo"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

169
ext_nodeinfo/src/lib.rs Normal file
View File

@ -0,0 +1,169 @@
use crate::version_1_0::NodeInfo10;
use crate::version_1_1::NodeInfo11;
use crate::version_2_0::NodeInfo20;
use crate::version_2_1::NodeInfo21;
use serde::{Deserialize, Serialize};
pub mod version_1_0;
pub mod version_1_1;
pub mod version_2_0;
pub mod version_2_1;
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(tag = "version")]
pub enum NodeInfo {
#[serde(rename = "1.0")]
V1_0(NodeInfo10),
#[serde(rename = "1.1")]
V1_1(NodeInfo11),
#[serde(rename = "2.0")]
V2_0(NodeInfo20),
#[serde(rename = "2.1")]
V2_1(NodeInfo21),
}
#[cfg(test)]
mod test {
use crate::version_1_0::{
NodeInfo10Services, NodeInfo10Software, NodeInfo10Usage, NodeInfo10UsageUsers,
};
use crate::version_2_0::NodeInfo20;
use crate::version_2_1::{NodeInfo21, NodeInfo21Software};
use crate::NodeInfo;
use serde_json::json;
use std::collections::{HashMap, HashSet};
fn json_mastodon() -> serde_json::Value {
json!({
"version": "2.0",
"software": {
"name": "mastodon",
"version": "4.1.0"
},
"protocols": [
"activitypub"
],
"services": {
"outbound": [],
"inbound": []
},
"usage": {
"users": {
"total": 10360,
"activeMonth": 4627,
"activeHalfyear": 10089
},
"localPosts": 1033206
},
"openRegistrations": true,
"metadata": {}
})
}
fn data_mastodon() -> NodeInfo20 {
NodeInfo20 {
software: NodeInfo10Software {
name: "mastodon".to_owned(),
version: "4.1.0".to_owned(),
},
protocols: HashSet::from(["activitypub".to_owned()]),
services: NodeInfo10Services {
inbound: HashSet::new(),
outbound: HashSet::new(),
},
open_registrations: true,
usage: NodeInfo10Usage {
users: NodeInfo10UsageUsers {
total: Some(10360),
active_halfyear: Some(10089),
active_month: Some(4627),
},
local_posts: Some(1033206),
local_comments: None,
},
metadata: HashMap::new(),
}
}
#[test]
fn should_serialize_nodeinfo_20() {
let json = json_mastodon();
let node_info = serde_json::to_value(NodeInfo::V2_0(data_mastodon())).unwrap();
assert_eq!(node_info, json);
}
#[test]
fn should_parse_nodeinfo_20() {
let json = json_mastodon();
let node_info: NodeInfo = serde_json::from_value(json).unwrap();
assert_eq!(node_info, NodeInfo::V2_0(data_mastodon()));
}
#[test]
fn should_parse_nodeinfo_21() {
let json = json!({
"version": "2.1",
"software": {
"name": "calckey",
"version": "13.1.2",
"repository": "https://github.com/misskey-dev/misskey",
"homepage": "https://calckey.cloud"
},
"protocols": [
"activitypub"
],
"services": {
"inbound": [],
"outbound": [
"atom1.0",
"rss2.0"
]
},
"openRegistrations": false,
"usage": {
"users": {
"total": 2,
"activeHalfyear": 1,
"activeMonth": 1
},
"localPosts": 1936,
"localComments": 0
},
"metadata": {}
});
let node_info: NodeInfo = serde_json::from_value(json).unwrap();
assert_eq!(
node_info,
NodeInfo::V2_1(NodeInfo21 {
software: NodeInfo21Software {
name: "calckey".to_owned(),
version: "13.1.2".to_owned(),
homepage: Some("https://calckey.cloud".to_owned()),
repository: Some("https://github.com/misskey-dev/misskey".to_owned())
},
protocols: HashSet::from(["activitypub".to_owned()]),
services: NodeInfo10Services {
inbound: HashSet::new(),
outbound: HashSet::from(["atom1.0".to_owned(), "rss2.0".to_owned()])
},
open_registrations: false,
usage: NodeInfo10Usage {
users: NodeInfo10UsageUsers {
total: Some(2),
active_halfyear: Some(1),
active_month: Some(1)
},
local_posts: Some(1936),
local_comments: Some(0)
},
metadata: HashMap::new()
})
);
}
}

View File

@ -0,0 +1,76 @@
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo10Protocols {
#[doc = "The protocols this server can receive traffic for."]
pub inbound: HashSet<String>,
#[doc = "The protocols this server can generate traffic for."]
pub outbound: HashSet<String>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo10Services {
#[doc = "The third party sites this server can retrieve messages from for combined display with "]
#[doc = "regular traffic."]
pub inbound: HashSet<String>,
#[doc = "The third party sites this server can publish messages to on the behalf of a user."]
pub outbound: HashSet<String>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo10Software {
#[doc = "The canonical name of this server software."]
pub name: String,
#[doc = "The version of this server software."]
pub version: String,
}
#[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)]
pub struct NodeInfo10UsageUsers {
#[doc = "The amount of users that signed in at least once in the last 180 days."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "activeHalfyear")]
pub active_halfyear: Option<i64>,
#[doc = "The amount of users that signed in at least once in the last 30 days."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "activeMonth")]
pub active_month: Option<i64>,
#[doc = "The total amount of on this server registered users."]
#[serde(skip_serializing_if = "Option::is_none")]
pub total: Option<i64>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo10Usage {
#[doc = "The amount of comments that were made by users that are registered on this server."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "localComments")]
pub local_comments: Option<i64>,
#[doc = "The amount of posts that were made by users that are registered on this server."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "localPosts")]
pub local_posts: Option<i64>,
#[doc = "statistics about the users of this server."]
pub users: NodeInfo10UsageUsers,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo10 {
#[doc = "The schema version, must be 1.0."]
pub version: String,
#[doc = "Free form key value pairs for software specific values. Clients should not rely on any "]
#[doc = "specific key present."]
pub metadata: HashMap<String, serde_json::Value>,
#[doc = "Whether this server allows open self-registration."]
#[serde(rename = "openRegistrations")]
pub open_registrations: bool,
#[doc = "The protocols supported on this server."]
pub protocols: NodeInfo10Protocols,
#[doc = "The third party sites this server can connect to via their application API."]
pub services: NodeInfo10Services,
#[doc = "Metadata about server software in use."]
pub software: NodeInfo10Protocols,
#[doc = "Usage statistics for this server."]
pub usage: NodeInfo10Usage,
}

View File

@ -0,0 +1,23 @@
use crate::version_1_0::{
NodeInfo10Protocols, NodeInfo10Services, NodeInfo10Software, NodeInfo10Usage,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo11 {
#[doc = "Free form key value pairs for software specific values. Clients should not rely on any "]
#[doc = "specific key present."]
pub metadata: HashMap<String, serde_json::Value>,
#[doc = "Whether this server allows open self-registration."]
#[serde(rename = "openRegistrations")]
pub open_registrations: bool,
#[doc = "The protocols supported on this server."]
pub protocols: NodeInfo10Protocols,
#[doc = "The third party sites this server can connect to via their application API."]
pub services: NodeInfo10Services,
#[doc = "Metadata about server software in use."]
pub software: NodeInfo10Software,
#[doc = "Usage statistics for this server."]
pub usage: NodeInfo10Usage,
}

View File

@ -0,0 +1,21 @@
use crate::version_1_0::{NodeInfo10Services, NodeInfo10Software, NodeInfo10Usage};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo20 {
#[doc = "Free form key value pairs for software specific values. Clients should not rely on any "]
#[doc = "specific key present."]
pub metadata: HashMap<String, serde_json::Value>,
#[doc = "Whether this server allows open self-registration."]
#[serde(rename = "openRegistrations")]
pub open_registrations: bool,
#[doc = "The protocols supported on this server."]
pub protocols: HashSet<String>,
#[doc = "The third party sites this server can connect to via their application API."]
pub services: NodeInfo10Services,
#[doc = "Metadata about server software in use."]
pub software: NodeInfo10Software,
#[doc = "Usage statistics for this server."]
pub usage: NodeInfo10Usage,
}

View File

@ -0,0 +1,35 @@
use crate::version_1_0::{NodeInfo10Services, NodeInfo10Usage};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo21Software {
#[doc = "The url of the homepage of this server software."]
#[serde(skip_serializing_if = "Option::is_none")]
pub homepage: Option<String>,
#[doc = "The canonical name of this server software."]
pub name: String,
#[doc = "The url of the source code repository of this server software."]
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option<String>,
#[doc = "The version of this server software."]
pub version: String,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct NodeInfo21 {
#[doc = "Free form key value pairs for software specific values. Clients should not rely on any "]
#[doc = "specific key present."]
pub metadata: HashMap<String, serde_json::Value>,
#[doc = "Whether this server allows open self-registration."]
#[serde(rename = "openRegistrations")]
pub open_registrations: bool,
#[doc = "The protocols supported on this server."]
pub protocols: HashSet<String>,
#[doc = "The third party sites this server can connect to via their application API."]
pub services: NodeInfo10Services,
#[doc = "Metadata about server software in use."]
pub software: NodeInfo21Software,
#[doc = "Usage statistics for this server."]
pub usage: NodeInfo10Usage,
}

64
src/config.rs Normal file
View File

@ -0,0 +1,64 @@
use anyhow::anyhow;
use serde::Deserialize;
use std::net::IpAddr;
use tracing::info;
#[derive(Deserialize, Debug)]
#[non_exhaustive]
pub struct MagnetarNetworking {
pub host: String,
pub port: u16,
pub bind_addr: IpAddr,
}
fn env_host() -> String {
std::env::var("MAG_C_HOST")
.expect("MAG_C_HOST or \"host\" in the default configuration must be set")
}
fn env_bind_addr() -> IpAddr {
std::env::var("MAG_C_BIND_ADDR")
.unwrap_or_else(|_| "::".to_owned())
.parse()
.map_err(|e| format!("Failed to parse \"MAG_C_BIND_ADDR\": {e}"))
.unwrap()
}
fn env_port() -> u16 {
std::env::var("MAG_C_PORT")
.unwrap_or_else(|_| "4939".to_owned())
.parse()
.expect("MAG_C_PORT must be a valid port number")
}
impl Default for MagnetarNetworking {
fn default() -> Self {
MagnetarNetworking {
host: env_host(),
bind_addr: env_bind_addr(),
port: env_port(),
}
}
}
#[derive(Deserialize, Debug, Default)]
#[non_exhaustive]
pub struct MagnetarConfig {
#[serde(default)]
pub networking: MagnetarNetworking,
}
pub fn load_config() -> anyhow::Result<MagnetarConfig> {
let path =
std::env::var("MAG_CONFIG_PATH").unwrap_or_else(|_| "config/default.toml".to_owned());
let str_cfg =
std::fs::read_to_string(path).map_err(|e| anyhow!("Failed to load configuration: {e}"))?;
let config =
toml::from_str(&str_cfg).map_err(|e| anyhow!("Failed to parse configuration: {e}"))?;
info!("Loaded configuration: {config:#?}");
Ok(config)
}

View File

@ -1,3 +1,4 @@
pub mod config;
pub mod webfinger;
use anyhow::{anyhow, Context};
@ -5,6 +6,7 @@ use axum::routing::get;
use axum::Router;
use dotenvy::dotenv;
use std::net::SocketAddr;
use std::sync::Arc;
use tower_http::cors::{Any, CorsLayer};
use tower_http::trace::TraceLayer;
use tracing::info;
@ -23,15 +25,21 @@ async fn main() -> anyhow::Result<()> {
.with_test_writer()
.init();
let port: u16 = std::env::var("SERVER_PORT")
.unwrap_or_else(|_| "4939".to_string())
.parse()
.context("SERVER_PORT not a number")?;
let config = Arc::new(config::load_config()?);
let well_known_router = Router::new().route("/webfinger", get(webfinger::handle_webfinger));
/*
let activity_pub_router = Router::new()
.route("/@!:id/outbox", get(activity_pub::handle_actor_get))
.route("/@:name/outbox", get(activity_pub::handle_actor_get))
.route("/@!:id", get(activity_pub::handle_actor_get))
.route("/@:name", get(activity_pub::handle_actor_get));
*/
let app = Router::new()
.nest("/.well-known", well_known_router)
//.nest("/", activity_pub_router)
.with_state(config.clone())
.layer(
CorsLayer::new()
.allow_headers(Any)
@ -40,7 +48,7 @@ async fn main() -> anyhow::Result<()> {
)
.layer(TraceLayer::new_for_http());
let addr = SocketAddr::from(([0, 0, 0, 0], port));
let addr = SocketAddr::from((config.networking.bind_addr, config.networking.port));
info!("Serving on: {addr}");
axum::Server::bind(&addr)
.serve(app.into_make_service())

View File

@ -12,6 +12,7 @@ pub struct WebFingerQuery {
rel: Option<Vec<String>>,
}
// TODO: Filter by rel
pub async fn handle_webfinger(
Query(WebFingerQuery { resource, rel, .. }): Query<WebFingerQuery>,
) -> Result<Json<WebFinger>, StatusCode> {
@ -24,8 +25,6 @@ pub async fn handle_webfinger(
other => other,
};
println!("{resource:?}");
Ok(Json(WebFinger {
subject: WebFingerSubject::Acct("natty@tech.lgbt".into()),
aliases: vec![