From 0b9739eb412a86a86d9587b3df0771a543ba207e Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 6 Jan 2026 15:46:40 +0100 Subject: [PATCH 1/6] chore: wip switch to axum Signed-off-by: Henry Gressmann --- Cargo.lock | 656 +++++++++++-------------------- Cargo.toml | 17 +- src/app/models.rs | 6 +- src/lib.rs | 1 + src/web/webext.rs | 28 +- src/web_axum/mod.rs | 96 +++++ src/web_axum/routes/admin.rs | 460 ++++++++++++++++++++++ src/web_axum/routes/auth.rs | 121 ++++++ src/web_axum/routes/dashboard.rs | 262 ++++++++++++ src/web_axum/routes/event.rs | 138 +++++++ src/web_axum/routes/mod.rs | 18 + src/web_axum/session.rs | 47 +++ src/web_axum/webext.rs | 128 ++++++ 13 files changed, 1524 insertions(+), 454 deletions(-) create mode 100644 src/web_axum/mod.rs create mode 100644 src/web_axum/routes/admin.rs create mode 100644 src/web_axum/routes/auth.rs create mode 100644 src/web_axum/routes/dashboard.rs create mode 100644 src/web_axum/routes/event.rs create mode 100644 src/web_axum/routes/mod.rs create mode 100644 src/web_axum/session.rs create mode 100644 src/web_axum/webext.rs diff --git a/Cargo.lock b/Cargo.lock index 0fd063d..672e5bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,41 +8,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "ahash" version = "0.7.8" @@ -78,18 +43,24 @@ dependencies = [ ] [[package]] -name = "alloc-no-stdlib" -version = "2.0.4" +name = "aide" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "6966317188cdfe54c58c0900a195d021294afb3ece9b7073d09e4018dbb1e3a2" dependencies = [ - "alloc-no-stdlib", + "axum", + "bytes 1.11.0", + "cfg-if", + "http", + "indexmap", + "schemars 0.9.0", + "serde", + "serde_json", + "serde_qs", + "thiserror 2.0.17", + "tower-layer", + "tower-service", + "tracing", ] [[package]] @@ -422,6 +393,78 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "bytes 1.11.0", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes 1.11.0", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-extra" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef252edff26ddba56bbcdf2ee3307b8129acb86f5749b68990c168a6fcc9c76" +dependencies = [ + "axum-core", + "bytes 1.11.0", + "cookie", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "tower-layer", + "tower-service", +] + [[package]] name = "base64" version = "0.22.1" @@ -443,7 +486,7 @@ dependencies = [ "bitflags", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools", "proc-macro2", "quote", "regex", @@ -511,27 +554,6 @@ dependencies = [ "syn 2.0.113", ] -[[package]] -name = "brotli" -version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bs58" version = "0.5.1" @@ -645,16 +667,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -702,7 +714,6 @@ version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" dependencies = [ - "brotli", "compression-core", "flate2", "memchr", @@ -736,29 +747,13 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "cookie" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ - "aes-gcm", - "base64", - "hkdf", - "hmac", "percent-encoding", - "rand 0.8.5", - "sha2", - "subtle", "time", "version_check", ] @@ -810,54 +805,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.113", -] - -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.113", -] - [[package]] name = "deranged" version = "0.5.5" @@ -878,29 +828,6 @@ dependencies = [ "syn 2.0.113", ] -[[package]] -name = "derive_more" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.113", - "unicode-xid", -] - [[package]] name = "digest" version = "0.10.7" @@ -948,6 +875,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "either" version = "1.15.0" @@ -1189,7 +1122,7 @@ dependencies = [ "bytes 0.5.6", "futures", "memchr", - "pin-project 0.4.30", + "pin-project", ] [[package]] @@ -1229,16 +1162,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - [[package]] name = "glob" version = "0.3.3" @@ -1357,24 +1280,6 @@ 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 = "http" version = "1.4.0" @@ -1589,12 +1494,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "1.1.0" @@ -1624,6 +1523,8 @@ checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -1632,15 +1533,6 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -1672,15 +1564,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.17" @@ -1889,12 +1772,15 @@ name = "liwan" version = "1.2.1" dependencies = [ "ahash 0.8.12", + "aide", "anyhow", "arc-swap", "argh", "argon2", "astral-tokio-tar", "async-compression", + "axum", + "axum-extra", "bs58", "chrono", "cookie", @@ -1905,7 +1791,6 @@ dependencies = [ "maxminddb", "md-5", "poem", - "poem-openapi", "quick_cache", "r2d2", "rand 0.9.2", @@ -1914,13 +1799,15 @@ dependencies = [ "reqwest 0.13.1", "rusqlite", "rust-embed", + "schemars 1.2.0", "serde", "serde_json", "sha3", "tikv-jemallocator", "tokio", "tokio-util", - "tower 0.5.2", + "tower", + "tower-http", "tracing", "tracing-subscriber", "ua-parser", @@ -1958,6 +1845,12 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "maxminddb" version = "0.27.1" @@ -2031,24 +1924,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "multer" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" -dependencies = [ - "bytes 1.11.0", - "encoding_rs", - "futures-util", - "http", - "httparse", - "memchr", - "mime", - "spin", - "tokio", - "version_check", -] - [[package]] name = "nix" version = "0.30.1" @@ -2172,12 +2047,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.2.0" @@ -2253,16 +2122,7 @@ version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef0f924a5ee7ea9cbcea77529dba45f8a9ba9f622419fe3386ca581a3ae9d5a" dependencies = [ - "pin-project-internal 0.4.30", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal 1.1.10", + "pin-project-internal", ] [[package]] @@ -2276,17 +2136,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.113", -] - [[package]] name = "pin-project-lite" version = "0.2.16" @@ -2311,43 +2160,31 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f977080932c87287147dca052951c3e2696f8759863f6b4e4c0c9ffe7a4cc8b" dependencies = [ - "async-compression", "bytes 1.11.0", - "chrono", - "cookie", "futures-util", "headers", - "hex", "http", "http-body-util", "hyper", "hyper-util", "mime", - "mime_guess", - "multer", "nix", "parking_lot", "percent-encoding", "pin-project-lite", "poem-derive", - "quick-xml", "regex", "rfc7239", - "rust-embed", "serde", "serde_json", "serde_urlencoded", - "serde_yaml", "smallvec", "sse-codec", "sync_wrapper", - "tempfile", "thiserror 2.0.17", - "time", "tokio", "tokio-stream", "tokio-util", - "tower 0.4.13", "tracing", "wildmatch", ] @@ -2364,63 +2201,6 @@ dependencies = [ "syn 2.0.113", ] -[[package]] -name = "poem-openapi" -version = "5.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ccbcc395bf4dd03df1da32da351b6b6732e4074ce27ddec315650e52a2be44c" -dependencies = [ - "base64", - "bytes 1.11.0", - "chrono", - "derive_more", - "futures-util", - "indexmap", - "itertools 0.14.0", - "mime", - "num-traits", - "poem", - "poem-openapi-derive", - "quick-xml", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "serde_yaml", - "thiserror 2.0.17", - "tokio", -] - -[[package]] -name = "poem-openapi-derive" -version = "5.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41273b691a3d467a8c44d05506afba9f7b6bd56c9cdf80123de13fe52d7ec587" -dependencies = [ - "darling", - "http", - "indexmap", - "mime", - "proc-macro-crate", - "proc-macro2", - "quote", - "regex", - "syn 2.0.113", - "thiserror 2.0.17", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - [[package]] name = "portable-atomic" version = "1.13.0" @@ -2502,16 +2282,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "quick-xml" -version = "0.36.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "quick_cache" version = "0.6.18" @@ -2689,6 +2459,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + [[package]] name = "refinery" version = "0.9.0" @@ -2760,7 +2550,7 @@ checksum = "4c11639076bf147be211b90e47790db89f4c22b6c8a9ca6e960833869da67166" dependencies = [ "aho-corasick", "indexmap", - "itertools 0.13.0", + "itertools", "nohash", "regex", "regex-syntax", @@ -2811,7 +2601,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", - "tower 0.5.2", + "tower", "tower-http", "tower-service", "url", @@ -2853,7 +2643,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-util", - "tower 0.5.2", + "tower", "tower-http", "tower-service", "url", @@ -2994,15 +2784,6 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "1.1.3" @@ -3131,6 +2912,57 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "indexmap", + "ref-cast", + "schemars_derive 0.9.0", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +dependencies = [ + "dyn-clone", + "ref-cast", + "schemars_derive 1.2.0", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5016d94c77c6d32f0b8e08b781f7dc8a90c2007d4e77472cc2807bc10a8438fe" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.113", +] + +[[package]] +name = "schemars_derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4908ad288c5035a8eb12cfdf0d49270def0a268ee162b75eeee0f85d155a7c45" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.113", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -3166,12 +2998,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - [[package]] name = "serde" version = "1.0.228" @@ -3202,6 +3028,17 @@ dependencies = [ "syn 2.0.113", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + [[package]] name = "serde_json" version = "1.0.148" @@ -3215,6 +3052,30 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_qs" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b417bedc008acbdf6d6b4bc482d29859924114bbe2650b7921fb68a261d0aa6" +dependencies = [ + "axum", + "futures", + "percent-encoding", + "serde", + "thiserror 2.0.17", +] + [[package]] name = "serde_spanned" version = "0.6.9" @@ -3236,19 +3097,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "sha1" version = "0.10.6" @@ -3346,12 +3194,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "sqlite-wasm-rs" version = "0.5.1" @@ -3383,12 +3225,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "strum" version = "0.26.3" @@ -3774,23 +3610,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project 1.1.10", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.5.2" @@ -3814,14 +3633,18 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ + "async-compression", "bitflags", "bytes 1.11.0", + "futures-core", "futures-util", "http", "http-body", "iri-string", "pin-project-lite", - "tower 0.5.2", + "tokio", + "tokio-util", + "tower", "tower-layer", "tower-service", ] @@ -3844,6 +3667,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3943,40 +3767,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-width" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 301dc32..4f99c65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,14 +46,17 @@ tracing-subscriber={version="0.3", features=["env-filter"]} ahash="0.8" # web -poem={version="3.1", default-features=false, features=[ - "embed", - "cookie", - "compression", - "tower-compat", -]} -poem-openapi={version="5.1", default-features=false, features=["chrono"]} +axum="0.8" +axum-extra={version="0.12", default-features=false, features=["cookie"]} tower={version="0.5", default-features=false, features=["limit"]} +tower-http={version="0.6", default-features=false, features=[ + "cors", + "compression-zstd", + "set-header", +]} +aide={version="0.15", default-features=false, features=["axum"]} +schemars={version="1.2", features=["derive"]} + ua-parser="0.2" rust-embed={version="8.9", features=["mime-guess"]} reqwest={version="0.13", default-features=false, features=["json", "stream", "charset", "rustls"]} diff --git a/src/app/models.rs b/src/app/models.rs index d4a1035..6d376fc 100644 --- a/src/app/models.rs +++ b/src/app/models.rs @@ -1,7 +1,7 @@ use std::fmt::Display; use chrono::{DateTime, Utc}; -use poem_openapi::Enum; +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone)] @@ -46,8 +46,8 @@ pub struct User { pub projects: Vec, } -#[derive(Debug, Enum, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Default)] -#[oai(rename_all = "snake_case")] +#[derive(Debug, JsonSchema, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Default)] +#[serde(rename_all = "snake_case")] pub enum UserRole { #[serde(rename = "admin")] Admin, diff --git a/src/lib.rs b/src/lib.rs index 705ddbb..1bfbb56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,4 @@ pub mod cli; pub mod config; pub mod utils; pub mod web; +pub mod web_axum; diff --git a/src/web/webext.rs b/src/web/webext.rs index 6116a5d..3eda1af 100644 --- a/src/web/webext.rs +++ b/src/web/webext.rs @@ -62,20 +62,6 @@ impl PoemErrExt for Result { } } -pub struct EmbeddedFilesEndpoint(PhantomData); - -impl Default for EmbeddedFilesEndpoint { - fn default() -> Self { - Self::new() - } -} - -impl EmbeddedFilesEndpoint { - pub fn new() -> Self { - Self(PhantomData) - } -} - pub type ApiResult = poem::Result; #[derive(Object, Serialize)] @@ -96,6 +82,20 @@ impl EmptyResponse { } } +pub struct EmbeddedFilesEndpoint(PhantomData); + +impl Default for EmbeddedFilesEndpoint { + fn default() -> Self { + Self::new() + } +} + +impl EmbeddedFilesEndpoint { + pub fn new() -> Self { + Self(PhantomData) + } +} + impl Endpoint for EmbeddedFilesEndpoint { type Output = Response; diff --git a/src/web_axum/mod.rs b/src/web_axum/mod.rs new file mode 100644 index 0000000..f092d8c --- /dev/null +++ b/src/web_axum/mod.rs @@ -0,0 +1,96 @@ +pub mod routes; +pub mod session; +pub mod webext; + +use std::net::SocketAddr; +use std::sync::Arc; + +use crate::app::models::Event; +use crate::{app::Liwan, web_axum::webext::StaticFile}; +use axum::Extension; +use axum::handler::Handler; +use axum::http::{Method, header}; +use axum::response::IntoResponse; +use axum::{Router, error_handling::HandleErrorLayer, http::StatusCode, routing::IntoMakeService}; +use routes::{dashboard_service, event_service}; +use std::sync::mpsc::Sender; +use tower::ServiceBuilder; +use tower_http::compression::CompressionLayer; +use tower_http::cors::{Any, CorsLayer}; +use tower_http::set_header::SetResponseHeaderLayer; + +use aide::{ + axum::{ + ApiRouter, IntoApiResponse, + routing::{get, post}, + }, + openapi::{Info, OpenApi}, +}; + +pub use session::SessionUser; + +use anyhow::{Context, Result}; +use rust_embed::RustEmbed; + +#[derive(RustEmbed, Clone)] +#[folder = "./web/dist"] +struct Files; + +#[derive(RustEmbed, Clone)] +#[folder = "./tracker"] +struct Script; + +#[derive(Clone)] +pub struct State { + pub app: Arc, + pub events: Sender, +} + +pub async fn start_webserver(app: Arc, events: Sender) -> Result<()> { + let router = Router::new(); + + let event_cors = CorsLayer::new().allow_methods([Method::POST]).allow_origin(Any).allow_credentials(false); + let script_cors = CorsLayer::new().allow_methods([Method::GET]).allow_origin(Any).allow_credentials(false); + + let set_headers = ServiceBuilder::new() + .layer(SetResponseHeaderLayer::if_not_present(header::X_FRAME_OPTIONS, "DENY")) + .layer(SetResponseHeaderLayer::if_not_present(header::X_CONTENT_TYPE_OPTIONS, "nosniff")) + .layer(SetResponseHeaderLayer::if_not_present(header::X_XSS_PROTECTION, "1; mode=block")) + .layer(SetResponseHeaderLayer::if_not_present( + header::CONTENT_SECURITY_POLICY, + "default-src 'self' data: 'unsafe-inline'; img-src 'self' data: https://*", + )) + .layer(SetResponseHeaderLayer::if_not_present(header::REFERRER_POLICY, "same-origin")); + + let dashboard = ApiRouter::new() + .merge(routes::admin::router()) + .merge(routes::auth::router()) + .merge(routes::dashboard::router()); + + let router = ApiRouter::new() + .nest("/api/event", routes::event::router().layer(event_cors)) + .nest("/api/dashboard", dashboard) + .route_service("/script.js", StaticFile::