From a69c24e561c8ae16dc730f7713f8d8da0bd25e0e Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Tue, 15 Jul 2025 08:42:19 +0200 Subject: feat: persist with sqlx --- .gitignore | 1 + Cargo.lock | 801 +++++++++++++++++++++++++++++++++- Cargo.toml | 6 +- sellershut.toml | 16 + src/entity/user.rs | 64 ++- src/main.rs | 48 +- src/server.rs | 14 + src/server/routes.rs | 14 +- src/server/routes/users.rs | 4 +- src/server/routes/users/get_outbox.rs | 77 ++++ src/server/routes/users/get_user.rs | 49 ++- src/server/routes/users/webfinger.rs | 23 +- src/state.rs | 17 +- 13 files changed, 1069 insertions(+), 65 deletions(-) create mode 100644 sellershut.toml create mode 100644 src/server/routes/users/get_outbox.rs diff --git a/.gitignore b/.gitignore index e3dc09e..3b539fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /docs/book/book +.env diff --git a/Cargo.lock b/Cargo.lock index bf320d7..eaa2246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -91,6 +97,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.98" @@ -119,6 +175,15 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -203,7 +268,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -223,6 +288,9 @@ name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -309,6 +377,52 @@ dependencies = [ "windows-link", ] +[[package]] +name = "clap" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -318,6 +432,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "config" +version = "0.15.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1eb4fb07bc7f012422df02766c7bd5971effb894f573865642f06fa3265440" +dependencies = [ + "pathdiff", + "serde", + "toml", + "winnow", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -339,6 +465,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -357,6 +498,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -419,6 +569,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + [[package]] name = "derive_builder" version = "0.20.2" @@ -459,6 +618,7 @@ dependencies = [ "block-buffer", "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -472,6 +632,12 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "dyn-clone" version = "1.0.19" @@ -483,6 +649,9 @@ name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] [[package]] name = "enum_delegate" @@ -514,6 +683,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "5.4.0" @@ -535,12 +715,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -592,6 +789,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -701,6 +909,59 @@ name = "hashbrown" version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] [[package]] name = "http" @@ -808,7 +1069,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 1.0.1", ] [[package]] @@ -1009,6 +1270,12 @@ dependencies = [ "serde", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.14.0" @@ -1055,6 +1322,16 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "litemap" version = "0.8.0" @@ -1111,6 +1388,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "memchr" version = "2.7.5" @@ -1192,6 +1479,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -1237,6 +1530,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "overload" version = "0.1.1" @@ -1269,9 +1568,15 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -1320,6 +1625,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "portable-atomic" version = "1.11.1" @@ -1335,6 +1646,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1583,7 +1900,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 1.0.1", ] [[package]] @@ -1715,6 +2032,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "secrecy" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" +dependencies = [ + "serde", + "zeroize", +] + [[package]] name = "sellershut" version = "0.1.0" @@ -1723,13 +2050,17 @@ dependencies = [ "anyhow", "async-trait", "axum", + "clap", + "config", "serde", + "sqlx", "stack-up", "tokio", "tower", "tower-http", "tracing", "url", + "uuid", ] [[package]] @@ -1781,6 +2112,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1793,6 +2133,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.9" @@ -1849,6 +2200,9 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -1865,6 +2219,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spki" @@ -1876,6 +2233,204 @@ dependencies = [ "der", ] +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown", + "hashlink", + "indexmap", + "log", + "memchr", + "once_cell", + "percent-encoding", + "rustls", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.12", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots 0.26.11", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.104", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.104", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.12", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.12", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror 2.0.12", + "time", + "tracing", + "url", + "uuid", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1888,11 +2443,25 @@ version = "0.1.0" source = "git+https://github.com/rtkay123/stack-up.git#939ce92c1da43bdfea0387de6716ef1f0713b619" dependencies = [ "bon", + "secrecy", "serde", "serde_json", + "sqlx", "thiserror 2.0.12", "tracing", "tracing-subscriber", + "url", +] + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", ] [[package]] @@ -2004,6 +2573,37 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.1" @@ -2069,6 +2669,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.15" @@ -2082,6 +2693,37 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_parser" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30" +dependencies = [ + "winnow", +] + [[package]] name = "tower" version = "0.5.2" @@ -2203,12 +2845,33 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + [[package]] name = "untrusted" version = "0.9.0" @@ -2233,6 +2896,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.17.0" @@ -2250,6 +2919,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -2280,6 +2955,12 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2384,6 +3065,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.1", +] + [[package]] name = "webpki-roots" version = "1.0.1" @@ -2393,6 +3083,16 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "whoami" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" +dependencies = [ + "redox_syscall", + "wasite", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2517,13 +3217,22 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2532,7 +3241,22 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -2541,14 +3265,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2560,18 +3284,36 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -2584,30 +3326,63 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.39.0" diff --git a/Cargo.toml b/Cargo.toml index 1bd7537..4dd7120 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,15 +12,19 @@ activitypub_federation = { version = "0.7.0-beta.5", default-features = false, f anyhow = "1.0.98" async-trait = "0.1.88" axum = { version = "0.8.4", features = ["macros"] } +clap = { version = "4.5.41", features = ["derive"] } +config = { version = "0.15.13", default-features = false, features = ["toml"] } serde = { version = "1.0.219", features = ["derive"] } +sqlx = { version = "0.8.6", features = ["macros", "migrate", "runtime-tokio", "time", "tls-rustls", "uuid"] } tokio = { version = "1.46.1", features = ["macros", "rt-multi-thread", "signal"] } tower-http = { version = "0.6.6", features = ["trace"] } tracing = "0.1.41" url = "2.5.4" +uuid = { version = "1.17.0", features = ["v7"] } [dependencies.stack-up] git = "https://github.com/rtkay123/stack-up.git" -features = ["tracing"] +features = ["api", "postgres", "tracing"] [dev-dependencies] tower = { version = "0.5.2", features = ["util"] } diff --git a/sellershut.toml b/sellershut.toml new file mode 100644 index 0000000..d1f54ce --- /dev/null +++ b/sellershut.toml @@ -0,0 +1,16 @@ +[application] +env = "development" +port = 2210 + +[monitoring] +log-level = "sellershut=trace,info" + +[database] +pool_size = 100 +port = 5432 +name = "sellershut" +host = "localhost" +password = "password" +user = "postgres" + +# vim:ft=toml diff --git a/src/entity/user.rs b/src/entity/user.rs index e136cb3..da22f00 100644 --- a/src/entity/user.rs +++ b/src/entity/user.rs @@ -8,36 +8,77 @@ use activitypub_federation::{ }; use async_trait::async_trait; use serde::{Deserialize, Serialize}; +use stack_up::Services; use tracing::trace; use url::Url; +use uuid::Uuid; use crate::{error::AppError, state::AppHandle}; #[derive(PartialEq, Clone, Debug)] pub(crate) struct User { + pub id: String, pub username: String, pub ap_id: ObjectId, pub private_key: Option, pub public_key: String, pub inbox: Url, + pub outbox: Option, } -impl User { - pub fn new(username: &str) -> Result { - trace!("creating a new user"); - let keys = generate_actor_keypair()?; - let stub = &format!("http://localhost/users/{username}"); +pub struct DbUser { + pub id: String, + pub username: String, + pub ap_id: String, + pub private_key: Option, + pub public_key: String, + pub inbox: String, + pub outbox: Option, + pub local: bool, +} +impl TryFrom for User { + type Error = AppError; + fn try_from(value: DbUser) -> Result { Ok(Self { - username: username.to_owned(), - ap_id: Url::parse(stub)?.into(), - private_key: Some(keys.private_key), - public_key: keys.public_key, - inbox: Url::parse(&format!("{stub}/inbox"))?, + id: value.id, + username: value.username, + ap_id: Url::parse(&value.ap_id)?.into(), + private_key: value.private_key, + public_key: value.public_key, + inbox: Url::parse(&value.inbox)?, + outbox: match value.outbox { + Some(ref url) => Some(Url::parse(url)?), + None => None, + }, }) } } +impl User { + pub async fn new(username: &str, services: &Services) -> Result { + trace!("creating keypair for new user"); + let keys = generate_actor_keypair()?; + let stub = &format!("http://localhost/users/{username}"); + let id = Uuid::now_v7(); + + trace!(id = ?id, "creating a new user"); + let user = sqlx::query_as!( + DbUser, + "insert into account (id, username, ap_id, private_key, public_key, inbox, outbox, local) values ($1, $2, $3, $4, $5, $6, $7, $8) returning *", + id, + username, + stub, + keys.private_key, + keys.public_key, + &format!("{stub}/inbox"), + &format!("{stub}/outbox"), + true + ).fetch_one(&services.postgres).await?; + Self::try_from(user) + } +} + #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Person { @@ -47,6 +88,8 @@ pub struct Person { id: ObjectId, inbox: Url, public_key: PublicKey, + #[serde(skip_serializing_if = "Option::is_none")] + outbox: Option, } #[async_trait] @@ -85,6 +128,7 @@ impl Object for User { id: self.ap_id.clone(), inbox: self.inbox.clone(), public_key: self.public_key(), + outbox: self.outbox.clone(), }) } diff --git a/src/main.rs b/src/main.rs index 1e5b259..68aedc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,19 +3,53 @@ mod error; mod server; mod state; -use stack_up::{Monitoring, tracing::Tracing}; +use std::net::{Ipv6Addr, SocketAddr}; + +use clap::Parser; +use stack_up::{Configuration, Services, tracing::Tracing}; use crate::{error::AppError, state::AppState}; +use tracing::{error, info}; + +/// sellershut +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// Path to config file + #[arg(short, long)] + config_file: Option, +} #[tokio::main] async fn main() -> Result<(), AppError> { - let _tracing = Tracing::builder().build(&Monitoring { - log_level: "trace".into(), - }); + let args = Args::parse(); + let config = include_str!("../sellershut.toml"); + + let mut config = config::Config::builder() + .add_source(config::File::from_str(config, config::FileFormat::Toml)); + + if let Some(cf) = args.config_file.as_ref().and_then(|v| v.to_str()) { + config = config.add_source(config::File::new(cf, config::FileFormat::Toml)); + }; + + let mut config: Configuration = config.build()?.try_deserialize()?; + config.application.name = env!("CARGO_CRATE_NAME").into(); + config.application.version = env!("CARGO_PKG_VERSION").into(); + + let _tracing = Tracing::builder().build(&config.monitoring); + + let services = Services::builder() + .postgres(&config.database) + .await + .inspect_err(|e| error!("database: {e}"))? + .build(); + + let state = AppState::new(services, &config).await?; + + let addr = SocketAddr::from((Ipv6Addr::UNSPECIFIED, config.application.port)); - let state = AppState::new().await?; - let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?; - tracing::debug!("listening on {}", listener.local_addr()?); + let listener = tokio::net::TcpListener::bind(addr).await?; + info!(port = addr.port(), "serving api"); axum::serve(listener, server::router(state)).await?; Ok(()) diff --git a/src/server.rs b/src/server.rs index bb2b4d0..85a3e81 100644 --- a/src/server.rs +++ b/src/server.rs @@ -13,3 +13,17 @@ pub fn router(state: FederationConfig) -> Router { .layer(TraceLayer::new_for_http()) .layer(FederationMiddleware::new(state)) } + +#[cfg(test)] +pub(crate) fn test_config() -> stack_up::Configuration { + use stack_up::Configuration; + + let config_path = "sellershut.toml"; + + let config = config::Config::builder() + .add_source(config::File::new(config_path, config::FileFormat::Toml)) + .build() + .unwrap(); + + config.try_deserialize::().unwrap() +} diff --git a/src/server/routes.rs b/src/server/routes.rs index 7751c95..85cc100 100644 --- a/src/server/routes.rs +++ b/src/server/routes.rs @@ -14,13 +14,19 @@ mod tests { body::Body, http::{Request, StatusCode}, }; + use sqlx::PgPool; + use stack_up::Services; use tower::ServiceExt; - use crate::{server, state::AppState}; + use crate::{ + server::{self, test_config}, + state::AppState, + }; - #[tokio::test] - async fn health_check() { - let state = AppState::new().await.unwrap(); + #[sqlx::test] + async fn health_check(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/server/routes/users.rs b/src/server/routes/users.rs index 2ef49b2..d3ce446 100644 --- a/src/server/routes/users.rs +++ b/src/server/routes/users.rs @@ -1,3 +1,4 @@ +pub mod get_outbox; pub mod get_user; pub mod webfinger; @@ -5,6 +6,7 @@ use axum::{Router, routing::get}; pub fn users_router() -> Router { Router::new() - .route("/users/{usernme}", get(get_user::http_get_user)) + .route("/users/{username}", get(get_user::http_get_user)) + .route("/users/{username}/outbox", get(get_outbox::http_get_outbox)) .route("/.well-known/webfinger", get(webfinger::webfinger)) } diff --git a/src/server/routes/users/get_outbox.rs b/src/server/routes/users/get_outbox.rs new file mode 100644 index 0000000..d5a4af5 --- /dev/null +++ b/src/server/routes/users/get_outbox.rs @@ -0,0 +1,77 @@ +use activitypub_federation::{ + axum::json::FederationJson, config::Data, protocol::context::WithContext, traits::Object, +}; +use axum::{debug_handler, extract::Path, http::StatusCode, response::IntoResponse}; + +use crate::{error::AppError, state::AppHandle}; + +#[debug_handler] +pub async fn http_get_outbox( + Path(name): Path, + data: Data, +) -> Result { + if let Some(a) = super::get_user::read_user(&name, &data).await? { + let json_user = a.into_json(&data).await?; + Ok(( + StatusCode::OK, + FederationJson(WithContext::new_default(json_user)), + ) + .into_response()) + } else { + Ok((StatusCode::NOT_FOUND, "").into_response()) + } +} + +#[cfg(test)] +mod tests { + use axum::{ + body::Body, + http::{Request, StatusCode}, + }; + use sqlx::PgPool; + use stack_up::Services; + use tower::ServiceExt; + + use crate::{ + server::{self, test_config}, + state::AppState, + }; + + #[sqlx::test] + async fn get_user(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); + let app = server::router(state); + + let response = app + .oneshot( + Request::builder() + .uri("/users/sellershut") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + } + + #[sqlx::test] + async fn get_user_not_found(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); + let app = server::router(state); + + let response = app + .oneshot( + Request::builder() + .uri("/users/selut") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::NOT_FOUND); + } +} diff --git a/src/server/routes/users/get_user.rs b/src/server/routes/users/get_user.rs index d86cc26..4079731 100644 --- a/src/server/routes/users/get_user.rs +++ b/src/server/routes/users/get_user.rs @@ -2,6 +2,7 @@ use activitypub_federation::{ axum::json::FederationJson, config::Data, protocol::context::WithContext, traits::Object, }; use axum::{debug_handler, extract::Path, http::StatusCode, response::IntoResponse}; +use tracing::trace; use crate::{error::AppError, state::AppHandle}; @@ -10,7 +11,7 @@ pub async fn http_get_user( Path(name): Path, data: Data, ) -> Result { - if let Some(a) = read_user(&name, &data).await { + if let Some(a) = read_user(&name, &data).await? { let json_user = a.into_json(&data).await?; Ok(( StatusCode::OK, @@ -22,11 +23,26 @@ pub async fn http_get_user( } } -pub async fn read_user(name: &str, data: &Data) -> Option { - let read = data.users.read().await; - read.iter() - .find(|value| value.username.eq(&name)) - .map(ToOwned::to_owned) +pub async fn read_user( + name: &str, + data: &Data, +) -> Result, AppError> { + trace!(username = name, "getting user"); + let read = sqlx::query_as!( + crate::entity::user::DbUser, + "select * from account where username = $1 and local = $2", + name, + true + ) + .fetch_optional(&data.services.postgres) + .await?; + + let user = read.into_iter().find(|value| value.username.eq(&name)); + let user = match user { + Some(user) => Some(crate::entity::user::User::try_from(user)?), + None => None, + }; + Ok(user) } #[cfg(test)] @@ -35,13 +51,19 @@ mod tests { body::Body, http::{Request, StatusCode}, }; + use sqlx::PgPool; + use stack_up::Services; use tower::ServiceExt; - use crate::{server, state::AppState}; + use crate::{ + server::{self, test_config}, + state::AppState, + }; - #[tokio::test] - async fn get_user() { - let state = AppState::new().await.unwrap(); + #[sqlx::test] + async fn get_user(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app @@ -57,9 +79,10 @@ mod tests { assert_eq!(response.status(), StatusCode::OK); } - #[tokio::test] - async fn get_user_not_found() { - let state = AppState::new().await.unwrap(); + #[sqlx::test] + async fn get_user_not_found(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/server/routes/users/webfinger.rs b/src/server/routes/users/webfinger.rs index 22975c2..8efeda6 100644 --- a/src/server/routes/users/webfinger.rs +++ b/src/server/routes/users/webfinger.rs @@ -17,7 +17,7 @@ pub async fn webfinger( data: Data, ) -> Result { let name = extract_webfinger_name(&query.resource, &data)?; - if let Some(db_user) = read_user(name, &data).await { + if let Some(db_user) = read_user(name, &data).await? { Ok(( StatusCode::OK, Json(build_webfinger_response( @@ -37,13 +37,19 @@ mod tests { body::Body, http::{Request, StatusCode}, }; + use sqlx::PgPool; + use stack_up::Services; use tower::ServiceExt; - use crate::{server, state::AppState}; + use crate::{ + server::{self, test_config}, + state::AppState, + }; - #[tokio::test] - async fn webfinger_ok() { - let state = AppState::new().await.unwrap(); + #[sqlx::test] + async fn webfinger_ok(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app @@ -59,9 +65,10 @@ mod tests { assert_eq!(response.status(), StatusCode::OK); } - #[tokio::test] - async fn webfinger_err() { - let state = AppState::new().await.unwrap(); + #[sqlx::test] + async fn webfinger_err(pool: PgPool) { + let services = Services { postgres: pool }; + let state = AppState::new(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/src/state.rs b/src/state.rs index d7c9136..5ced62e 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,7 +1,7 @@ use std::{ops::Deref, sync::Arc}; use activitypub_federation::config::FederationConfig; -use tokio::sync::RwLock; +use stack_up::{Configuration, Environment, Services}; use crate::{entity::user::User, error::AppError}; @@ -17,23 +17,24 @@ impl Deref for AppHandle { } pub struct AppState { - pub users: RwLock>, + pub services: Services, } impl AppState { - pub async fn new() -> Result, AppError> { - let user = User::new("sellershut")?; + pub async fn new( + services: Services, + configuration: &Configuration, + ) -> Result, AppError> { + let user = User::new("sellershut", &services).await?; let domain = "localhost"; let config = FederationConfig::builder() .domain(domain) .signed_fetch_actor(&user) - .app_data(AppHandle(Arc::new(Self { - users: RwLock::new(vec![user]), - }))) + .app_data(AppHandle(Arc::new(Self { services }))) // .url_verifier(Box::new(MyUrlVerifier())) // TODO: could change this to env variable? - .debug(cfg!(debug_assertions)) + .debug(configuration.application.env == Environment::Development) .build() .await?; -- cgit v1.2.3