From e11f703f87f217214079d3993cd5c0ef8ac33479 Mon Sep 17 00:00:00 2001 From: perfectra1n Date: Fri, 19 Dec 2025 20:33:13 -0800 Subject: [PATCH 1/2] feat(dev): update rust deps major versions --- Cargo.lock | 600 +++++++++++------- Cargo.toml | 16 +- src/oidc.rs | 38 +- ...ration_office_document_extraction_tests.rs | 4 +- tests/integration_office_extraction.rs | 18 +- 5 files changed, 430 insertions(+), 246 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4a6cf7..e12e3d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,6 +187,22 @@ dependencies = [ "serde_json", ] +[[package]] +name = "astral-tokio-tar" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec179a06c1769b1e42e1e2cbe74c7dcdb3d6383c838454d063eaac5bbb7ebbe5" +dependencies = [ + "filetime", + "futures-core", + "libc", + "portable-atomic", + "rustc-hash 2.1.1", + "tokio", + "tokio-stream", + "xattr", +] + [[package]] name = "async-stream" version = "0.3.6" @@ -743,7 +759,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-tungstenite", "tower", @@ -765,7 +781,7 @@ dependencies = [ "http-body-util", "mime", "pin-project-lite", - "sync_wrapper 1.0.2", + "sync_wrapper", "tower-layer", "tower-service", "tracing", @@ -777,12 +793,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -840,7 +850,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 1.0.109", "which", @@ -863,7 +873,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 2.0.103", "which", @@ -920,13 +930,17 @@ dependencies = [ [[package]] name = "bollard" -version = "0.18.1" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ccca1260af6a459d75994ad5acc1651bcabcbdbc41467cc9786519ab854c30" +checksum = "87a52479c9237eb04047ddb94788c41ca0d26eaff8b697ecfbb4c32f7fdc3b1b" dependencies = [ + "async-stream", "base64 0.22.1", + "bitflags 2.9.1", + "bollard-buildkit-proto", "bollard-stubs", "bytes", + "chrono", "futures-core", "futures-util", "hex", @@ -939,10 +953,12 @@ dependencies = [ "hyper-util", "hyperlocal", "log", + "num", "pin-project-lite", + "rand 0.9.1", "rustls 0.23.31", "rustls-native-certs", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_derive", @@ -951,19 +967,40 @@ dependencies = [ "serde_urlencoded", "thiserror 2.0.17", "tokio", + "tokio-stream", "tokio-util", + "tonic", "tower-service", "url", "winapi", ] [[package]] -name = "bollard-stubs" -version = "1.47.1-rc.27.3.1" +name = "bollard-buildkit-proto" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f179cfbddb6e77a5472703d4b30436bff32929c0aa8a9008ecf23d1d3cdd0da" +checksum = "85a885520bf6249ab931a764ffdb87b0ceef48e6e7d807cfdb21b751e086e1ad" dependencies = [ + "prost", + "prost-types", + "tonic", + "tonic-prost", + "ureq", +] + +[[package]] +name = "bollard-stubs" +version = "1.49.1-rc.28.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5731fe885755e92beff1950774068e0cae67ea6ec7587381536fca84f1779623" +dependencies = [ + "base64 0.22.1", + "bollard-buildkit-proto", + "bytes", + "chrono", + "prost", "serde", + "serde_json", "serde_repr", "serde_with", ] @@ -1016,22 +1053,11 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.4.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", + "libbz2-rs-sys", ] [[package]] @@ -1071,6 +1097,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.42" @@ -1184,9 +1216,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" -version = "0.1.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "core-foundation" @@ -1434,6 +1466,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" +[[package]] +name = "deflate64" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" + [[package]] name = "der" version = "0.6.1" @@ -1638,13 +1676,12 @@ dependencies = [ [[package]] name = "etcetera" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c7b13d0780cb82722fd59f6f57f925e143427e4a75313a6c77243bf5326ae6" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" dependencies = [ "cfg-if", - "home", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1708,6 +1745,17 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "ferroid" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce161062fb044bd629c2393590efd47cab8d0241faf15704ffb0d47b7b4e4a35" +dependencies = [ + "portable-atomic", + "rand 0.9.1", + "web-time", +] + [[package]] name = "ff" version = "0.12.1" @@ -1933,9 +1981,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -2291,6 +2341,20 @@ dependencies = [ "tokio", "tokio-rustls 0.26.2", "tower-service", + "webpki-roots 1.0.0", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper 1.8.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", ] [[package]] @@ -2328,7 +2392,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2 0.6.0", - "system-configuration 0.6.1", + "system-configuration", "tokio", "tower-service", "tracing", @@ -2760,6 +2824,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libbz2-rs-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" + [[package]] name = "libc" version = "0.2.173" @@ -2783,7 +2853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.53.2", ] [[package]] @@ -2800,7 +2870,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.9.1", "libc", - "redox_syscall 0.5.13", + "redox_syscall", ] [[package]] @@ -2884,6 +2954,22 @@ dependencies = [ "hashbrown 0.15.4", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lzma-rust2" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48172246aa7c3ea28e423295dd1ca2589a24617cc4e588bb8cfe177cb2c54d95" +dependencies = [ + "crc", + "sha2", +] + [[package]] name = "matchers" version = "0.2.0" @@ -3222,16 +3308,16 @@ dependencies = [ [[package]] name = "oauth2" -version = "4.4.2" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" +checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "chrono", "getrandom 0.2.16", - "http 0.2.12", + "http 1.3.1", "rand 0.8.5", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "serde_path_to_error", @@ -3365,7 +3451,7 @@ checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.13", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -3395,17 +3481,6 @@ dependencies = [ "syn 2.0.103", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "paste" version = "1.0.15" @@ -3420,14 +3495,12 @@ checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest", "hmac", - "password-hash", - "sha2", ] [[package]] @@ -3543,6 +3616,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "portable-atomic" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" + [[package]] name = "potential_utf" version = "0.1.2" @@ -3558,6 +3637,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppmd-rust" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d558c559f0450f16f2a27a1f017ef38468c1090c9ce63c8e51366232d53717b4" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -3605,6 +3690,38 @@ dependencies = [ "syn 2.0.103", ] +[[package]] +name = "prost" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.103", +] + +[[package]] +name = "prost-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" +dependencies = [ + "prost", +] + [[package]] name = "pxfm" version = "0.1.25" @@ -3639,6 +3756,61 @@ dependencies = [ "serde", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls 0.23.31", + "socket2 0.6.0", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.1", + "ring", + "rustc-hash 2.1.1", + "rustls 0.23.31", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.0", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.40" @@ -3841,11 +4013,11 @@ dependencies = [ "oauth2", "once_cell", "quick-xml", - "rand 0.8.5", + "rand 0.9.1", "raw-cpuid", "readur", "regex", - "reqwest 0.12.25", + "reqwest", "rust_xlsxwriter", "serde", "serde_json", @@ -3871,16 +4043,7 @@ dependencies = [ "uuid", "walkdir", "wiremock", - "zip 0.6.6", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", + "zip 7.0.0", ] [[package]] @@ -3959,47 +4122,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.25.4", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.25" @@ -4026,13 +4148,16 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite", + "quinn", + "rustls 0.23.31", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-native-tls", + "tokio-rustls 0.26.2", "tower", "tower-http", "tower-service", @@ -4040,6 +4165,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 1.0.0", ] [[package]] @@ -4142,6 +4268,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustc_version" version = "0.4.1" @@ -4196,6 +4328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "aws-lc-rs", + "log", "once_cell", "ring", "rustls-pki-types", @@ -4216,15 +4349,6 @@ dependencies = [ "security-framework 3.2.0", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -4240,6 +4364,7 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ + "web-time", "zeroize", ] @@ -4937,12 +5062,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -4977,17 +5096,6 @@ dependencies = [ "windows", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "system-configuration-sys 0.5.0", -] - [[package]] name = "system-configuration" version = "0.6.1" @@ -4996,17 +5104,7 @@ checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.9.1", "core-foundation 0.9.4", - "system-configuration-sys 0.6.0", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "system-configuration-sys", ] [[package]] @@ -5029,7 +5127,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.0.7", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5068,18 +5166,20 @@ dependencies = [ [[package]] name = "testcontainers" -version = "0.24.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bb7577dca13ad86a78e8271ef5d322f37229ec83b8d98da6d996c588a1ddb1" +checksum = "1483605f58b2fff80d786eb56a0b6b4e8b1e5423fbc9ec2e3e562fa2040d6f27" dependencies = [ + "astral-tokio-tar", "async-trait", "bollard", - "bollard-stubs", "bytes", "docker_credential", "either", - "etcetera 0.10.0", + "etcetera 0.11.0", + "ferroid", "futures", + "itertools 0.14.0", "log", "memchr", "parse-display", @@ -5090,16 +5190,15 @@ dependencies = [ "thiserror 2.0.17", "tokio", "tokio-stream", - "tokio-tar", "tokio-util", "url", ] [[package]] name = "testcontainers-modules" -version = "0.12.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac95cde96549fc19c6bf19ef34cc42bd56e264c1cb97e700e21555be0ecf9e2" +checksum = "5e75e78ff453128a2c7da9a5d5a3325ea34ea214d4bf51eab3417de23a4e5147" dependencies = [ "testcontainers", ] @@ -5292,21 +5391,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-tar" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5714c010ca3e5c27114c1cdeb9d14641ace49874aa5626d7149e47aedace75" -dependencies = [ - "filetime", - "futures-core", - "libc", - "redox_syscall 0.3.5", - "tokio", - "tokio-stream", - "xattr", -] - [[package]] name = "tokio-test" version = "0.4.4" @@ -5345,6 +5429,46 @@ dependencies = [ "tokio", ] +[[package]] +name = "tonic" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +dependencies = [ + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2 0.4.12", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2 0.6.0", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-prost" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +dependencies = [ + "bytes", + "prost", + "tonic", +] + [[package]] name = "tower" version = "0.5.2" @@ -5353,9 +5477,12 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", + "indexmap 2.9.0", "pin-project-lite", - "sync_wrapper 1.0.2", + "slab", + "sync_wrapper", "tokio", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -5537,6 +5664,34 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "3.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" +dependencies = [ + "base64 0.22.1", + "log", + "percent-encoding", + "rustls 0.23.31", + "rustls-pki-types", + "ureq-proto", + "utf-8", + "webpki-roots 1.0.0", +] + +[[package]] +name = "ureq-proto" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" +dependencies = [ + "base64 0.22.1", + "http 1.3.1", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.7" @@ -5785,10 +5940,14 @@ dependencies = [ ] [[package]] -name = "webpki-roots" -version = "0.25.4" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "webpki-roots" @@ -5832,7 +5991,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ - "redox_syscall 0.5.13", + "redox_syscall", "wasite", ] @@ -5868,7 +6027,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -6235,16 +6394,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "wiremock" version = "0.6.5" @@ -6390,6 +6539,20 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.103", +] [[package]] name = "zerotrie" @@ -6424,26 +6587,6 @@ dependencies = [ "syn 2.0.103", ] -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2", - "sha1", - "time", - "zstd", -] - [[package]] name = "zip" version = "3.0.0" @@ -6472,6 +6615,34 @@ dependencies = [ "zopfli", ] +[[package]] +name = "zip" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd8a47718a4ee5fe78e07667cd36f3de80e7c2bfe727c7074245ffc7303c037" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "deflate64", + "flate2", + "generic-array", + "getrandom 0.3.3", + "hmac", + "indexmap 2.9.0", + "lzma-rust2", + "memchr", + "pbkdf2", + "ppmd-rust", + "sha1", + "time", + "zeroize", + "zopfli", + "zstd", +] + [[package]] name = "zlib-rs" version = "0.5.1" @@ -6492,20 +6663,19 @@ dependencies = [ [[package]] name = "zstd" -version = "0.11.2+zstd.1.5.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ - "libc", "zstd-sys", ] diff --git a/Cargo.toml b/Cargo.toml index ffa5171..f19c378 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ raw-cpuid = { version = "11", optional = true } reqwest = { version = "0.12", features = ["json", "multipart"] } quick-xml = { version = "0.37", features = ["serialize"] } urlencoding = "2.1" -oauth2 = "4.4" +oauth2 = "5" url = "2.4" dotenvy = "0.15" hostname = "0.4" @@ -65,11 +65,11 @@ aws-credential-types = { version = "1.2", optional = true } aws-types = { version = "1.3", optional = true } sha2 = "0.10" utoipa-swagger-ui = { version = "9", features = ["axum"] } -testcontainers = { version = "0.24", optional = true } -testcontainers-modules = { version = "0.12", features = ["postgres"], optional = true } +testcontainers = { version = "0.26", optional = true } +testcontainers-modules = { version = "0.14", features = ["postgres"], optional = true } # Office document support - now using XML extraction only -zip = "0.6" # Still needed for other archive handling -rand = "0.8" +zip = "7" # Still needed for other archive handling +rand = "0.9" [features] default = ["ocr", "s3"] @@ -83,10 +83,10 @@ tempfile = "3" wiremock = "0.6" tokio-test = "0.4" futures = "0.3" -rand = "0.8" +rand = "0.9" # Database testing dependencies -testcontainers = "0.24" -testcontainers-modules = { version = "0.12", features = ["postgres"] } +testcontainers = "0.26" +testcontainers-modules = { version = "0.14", features = ["postgres"] } # Dependencies for creating proper test Office documents rust_xlsxwriter = "0.92" # For creating proper XLSX test files # WebDAV server for realistic stress testing diff --git a/src/oidc.rs b/src/oidc.rs index 3ae5f31..c6bba57 100644 --- a/src/oidc.rs +++ b/src/oidc.rs @@ -1,7 +1,8 @@ use anyhow::{anyhow, Result}; use oauth2::{ - basic::BasicClient, reqwest::async_http_client, AuthUrl, AuthorizationCode, ClientId, - ClientSecret, CsrfToken, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, Scope, TokenResponse, TokenUrl, + basic::BasicClient, AuthUrl, AuthorizationCode, ClientId, + ClientSecret, CsrfToken, EndpointNotSet, EndpointSet, PkceCodeChallenge, PkceCodeVerifier, + RedirectUrl, Scope, TokenResponse, TokenUrl, }; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -12,6 +13,11 @@ use url::Url; use crate::config::Config; +// Type alias for the fully-configured OAuth2 client (oauth2 5.0 uses typestate pattern) +// HasAuthUrl=EndpointSet, HasDeviceAuthUrl=EndpointNotSet, HasIntrospectionUrl=EndpointNotSet, +// HasRevocationUrl=EndpointNotSet, HasTokenUrl=EndpointSet +type ConfiguredBasicClient = BasicClient; + #[derive(Debug, Serialize, Deserialize)] pub struct OidcDiscovery { pub authorization_endpoint: String, @@ -33,7 +39,7 @@ type PkceStore = Mutex>; #[derive(Debug)] pub struct OidcClient { - oauth_client: BasicClient, + oauth_client: ConfiguredBasicClient, discovery: OidcDiscovery, http_client: Client, is_public_client: bool, @@ -69,14 +75,15 @@ impl OidcClient { // Discover OIDC endpoints let discovery = Self::discover_endpoints(&http_client, issuer_url).await?; - // Create OAuth2 client - let oauth_client = BasicClient::new( - ClientId::new(client_id.clone()), - client_secret_opt.map(|s| ClientSecret::new(s.clone())), - AuthUrl::new(discovery.authorization_endpoint.clone())?, - Some(TokenUrl::new(discovery.token_endpoint.clone())?), - ) - .set_redirect_uri(RedirectUrl::new(redirect_uri.clone())?); + // Create OAuth2 client using builder pattern (oauth2 5.0 API) + let mut oauth_client = BasicClient::new(ClientId::new(client_id.clone())) + .set_auth_uri(AuthUrl::new(discovery.authorization_endpoint.clone())?) + .set_token_uri(TokenUrl::new(discovery.token_endpoint.clone())?) + .set_redirect_uri(RedirectUrl::new(redirect_uri.clone())?); + + if let Some(secret) = client_secret_opt { + oauth_client = oauth_client.set_client_secret(ClientSecret::new(secret.clone())); + } Ok(Self { oauth_client, @@ -166,8 +173,15 @@ impl OidcClient { } } + // Create HTTP client for token exchange (oauth2 5.0 uses reqwest::Client directly) + // Note: For SSRF protection, consider using redirect::Policy::none() in production + let oauth_http_client = Client::builder() + .redirect(reqwest::redirect::Policy::none()) + .build() + .map_err(|e| anyhow!("Failed to build HTTP client: {}", e))?; + let token_result = token_request - .request_async(async_http_client) + .request_async(&oauth_http_client) .await .map_err(|e| anyhow!("Failed to exchange authorization code: {}", e))?; diff --git a/tests/integration_office_document_extraction_tests.rs b/tests/integration_office_document_extraction_tests.rs index be6567b..1675823 100644 --- a/tests/integration_office_document_extraction_tests.rs +++ b/tests/integration_office_document_extraction_tests.rs @@ -4,7 +4,7 @@ use readur::services::file_service::FileService; use std::fs; use std::io::Write; use tempfile::TempDir; -use zip::write::FileOptions; +use zip::write::SimpleFileOptions; use zip::{ZipWriter, CompressionMethod}; /// Helper function to create a proper DOCX file for testing @@ -13,7 +13,7 @@ fn create_test_docx(content: &str) -> Vec { let mut buffer = Vec::new(); { let mut zip = ZipWriter::new(std::io::Cursor::new(&mut buffer)); - let options = FileOptions::default().compression_method(CompressionMethod::Deflated); + let options = SimpleFileOptions::default().compression_method(CompressionMethod::Deflated); // Add [Content_Types].xml - More comprehensive structure zip.start_file("[Content_Types].xml", options).unwrap(); diff --git a/tests/integration_office_extraction.rs b/tests/integration_office_extraction.rs index 0396cf1..9e27c9e 100644 --- a/tests/integration_office_extraction.rs +++ b/tests/integration_office_extraction.rs @@ -30,7 +30,7 @@ impl OfficeTestDocuments { let mut zip = zip::ZipWriter::new(file); // Add [Content_Types].xml - zip.start_file("[Content_Types].xml", zip::write::FileOptions::default())?; + zip.start_file("[Content_Types].xml", zip::write::SimpleFileOptions::default())?; zip.write_all(br#" @@ -39,14 +39,14 @@ impl OfficeTestDocuments { "#)?; // Add _rels/.rels - zip.start_file("_rels/.rels", zip::write::FileOptions::default())?; + zip.start_file("_rels/.rels", zip::write::SimpleFileOptions::default())?; zip.write_all(br#" "#)?; // Add word/document.xml with the actual content - zip.start_file("word/document.xml", zip::write::FileOptions::default())?; + zip.start_file("word/document.xml", zip::write::SimpleFileOptions::default())?; let document_xml = format!(r#" @@ -72,7 +72,7 @@ impl OfficeTestDocuments { let mut zip = zip::ZipWriter::new(file); // Add [Content_Types].xml with shared strings support - zip.start_file("[Content_Types].xml", zip::write::FileOptions::default())?; + zip.start_file("[Content_Types].xml", zip::write::SimpleFileOptions::default())?; zip.write_all(br#" @@ -83,14 +83,14 @@ impl OfficeTestDocuments { "#)?; // Add _rels/.rels - zip.start_file("_rels/.rels", zip::write::FileOptions::default())?; + zip.start_file("_rels/.rels", zip::write::SimpleFileOptions::default())?; zip.write_all(br#" "#)?; // Add xl/workbook.xml - zip.start_file("xl/workbook.xml", zip::write::FileOptions::default())?; + zip.start_file("xl/workbook.xml", zip::write::SimpleFileOptions::default())?; zip.write_all(br#" @@ -99,7 +99,7 @@ impl OfficeTestDocuments { "#)?; // Add xl/_rels/workbook.xml.rels with shared strings relationship - zip.start_file("xl/_rels/workbook.xml.rels", zip::write::FileOptions::default())?; + zip.start_file("xl/_rels/workbook.xml.rels", zip::write::SimpleFileOptions::default())?; zip.write_all(br#" @@ -107,7 +107,7 @@ impl OfficeTestDocuments { "#)?; // Add xl/sharedStrings.xml with the text content - zip.start_file("xl/sharedStrings.xml", zip::write::FileOptions::default())?; + zip.start_file("xl/sharedStrings.xml", zip::write::SimpleFileOptions::default())?; let mut shared_strings_xml = String::from(r#" "#); shared_strings_xml = shared_strings_xml.replace("{count}", &content.len().to_string()); @@ -122,7 +122,7 @@ impl OfficeTestDocuments { zip.write_all(shared_strings_xml.as_bytes())?; // Add xl/worksheets/sheet1.xml with references to shared strings - zip.start_file("xl/worksheets/sheet1.xml", zip::write::FileOptions::default())?; + zip.start_file("xl/worksheets/sheet1.xml", zip::write::SimpleFileOptions::default())?; let mut worksheet_xml = String::from(r#" "#); From bc85daa45010c732b7fd8c8461bd9830e40cc02b Mon Sep 17 00:00:00 2001 From: perfectra1n Date: Fri, 19 Dec 2025 21:49:46 -0800 Subject: [PATCH 2/2] feat(oidc): just create the client on-demand --- src/oidc.rs | 77 ++++++++++++++++++++--------------- src/routes/auth.rs | 6 ++- tests/unit_oidc_unit_tests.rs | 2 +- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/oidc.rs b/src/oidc.rs index c6bba57..bb74103 100644 --- a/src/oidc.rs +++ b/src/oidc.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Result}; use oauth2::{ basic::BasicClient, AuthUrl, AuthorizationCode, ClientId, - ClientSecret, CsrfToken, EndpointNotSet, EndpointSet, PkceCodeChallenge, PkceCodeVerifier, + ClientSecret, CsrfToken, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, Scope, TokenResponse, TokenUrl, }; use reqwest::Client; @@ -13,11 +13,6 @@ use url::Url; use crate::config::Config; -// Type alias for the fully-configured OAuth2 client (oauth2 5.0 uses typestate pattern) -// HasAuthUrl=EndpointSet, HasDeviceAuthUrl=EndpointNotSet, HasIntrospectionUrl=EndpointNotSet, -// HasRevocationUrl=EndpointNotSet, HasTokenUrl=EndpointSet -type ConfiguredBasicClient = BasicClient; - #[derive(Debug, Serialize, Deserialize)] pub struct OidcDiscovery { pub authorization_endpoint: String, @@ -39,7 +34,14 @@ type PkceStore = Mutex>; #[derive(Debug)] pub struct OidcClient { - oauth_client: ConfiguredBasicClient, + // Store configuration instead of the oauth2 client to avoid complex typestate types. + // The oauth2 5.0 crate uses a typestate pattern that makes storing a configured client + // in a struct unwieldy. Instead, we store the config and build the client on-demand. + // This is cheap: just struct construction with pre-validated URLs (no network calls). + // The expensive OIDC discovery happens once in `new()`. + client_id: String, + client_secret: Option, + redirect_uri: String, discovery: OidcDiscovery, http_client: Client, is_public_client: bool, @@ -55,11 +57,12 @@ impl OidcClient { let client_id = config .oidc_client_id .as_ref() - .ok_or_else(|| anyhow!("OIDC client ID not configured"))?; + .ok_or_else(|| anyhow!("OIDC client ID not configured"))? + .clone(); // Client secret is optional - if not provided, this is a public client - let client_secret_opt = config.oidc_client_secret.as_ref(); - let is_public_client = client_secret_opt.is_none(); + let client_secret = config.oidc_client_secret.clone(); + let is_public_client = client_secret.is_none(); let issuer_url = config .oidc_issuer_url @@ -68,25 +71,18 @@ impl OidcClient { let redirect_uri = config .oidc_redirect_uri .as_ref() - .ok_or_else(|| anyhow!("OIDC redirect URI not configured"))?; + .ok_or_else(|| anyhow!("OIDC redirect URI not configured"))? + .clone(); let http_client = Client::new(); // Discover OIDC endpoints let discovery = Self::discover_endpoints(&http_client, issuer_url).await?; - // Create OAuth2 client using builder pattern (oauth2 5.0 API) - let mut oauth_client = BasicClient::new(ClientId::new(client_id.clone())) - .set_auth_uri(AuthUrl::new(discovery.authorization_endpoint.clone())?) - .set_token_uri(TokenUrl::new(discovery.token_endpoint.clone())?) - .set_redirect_uri(RedirectUrl::new(redirect_uri.clone())?); - - if let Some(secret) = client_secret_opt { - oauth_client = oauth_client.set_client_secret(ClientSecret::new(secret.clone())); - } - Ok(Self { - oauth_client, + client_id, + client_secret, + redirect_uri, discovery, http_client, is_public_client, @@ -96,7 +92,7 @@ impl OidcClient { async fn discover_endpoints(client: &Client, issuer_url: &str) -> Result { let discovery_url = format!("{}/.well-known/openid-configuration", issuer_url.trim_end_matches('/')); - + let response = client .get(&discovery_url) .send() @@ -118,11 +114,21 @@ impl OidcClient { Ok(discovery) } - pub fn get_authorization_url(&self) -> (Url, CsrfToken) { + pub fn get_authorization_url(&self) -> Result<(Url, CsrfToken)> { // Clean up expired PKCE verifiers (older than 10 minutes) self.cleanup_expired_verifiers(); - let mut auth_request = self.oauth_client + // Build OAuth2 client on-demand - this is cheap (just struct construction, no I/O) + let mut oauth_client = BasicClient::new(ClientId::new(self.client_id.clone())) + .set_auth_uri(AuthUrl::new(self.discovery.authorization_endpoint.clone())?) + .set_token_uri(TokenUrl::new(self.discovery.token_endpoint.clone())?) + .set_redirect_uri(RedirectUrl::new(self.redirect_uri.clone())?); + + if let Some(secret) = &self.client_secret { + oauth_client = oauth_client.set_client_secret(ClientSecret::new(secret.clone())); + } + + let mut auth_request = oauth_client .authorize_url(CsrfToken::new_random) .add_scope(Scope::new("openid".to_string())) .add_scope(Scope::new("email".to_string())) @@ -141,10 +147,10 @@ impl OidcClient { csrf_token.secret().clone(), (pkce_verifier, Instant::now() + Duration::from_secs(600)), // 10 minute expiry ); - (url, csrf_token) + Ok((url, csrf_token)) } else { // Confidential client - no PKCE needed - auth_request.url() + Ok(auth_request.url()) } } @@ -155,8 +161,17 @@ impl OidcClient { } pub async fn exchange_code(&self, code: &str, state: Option<&str>) -> Result { - let mut token_request = self - .oauth_client + // Build OAuth2 client on-demand - this is cheap (just struct construction, no I/O) + let mut oauth_client = BasicClient::new(ClientId::new(self.client_id.clone())) + .set_auth_uri(AuthUrl::new(self.discovery.authorization_endpoint.clone())?) + .set_token_uri(TokenUrl::new(self.discovery.token_endpoint.clone())?) + .set_redirect_uri(RedirectUrl::new(self.redirect_uri.clone())?); + + if let Some(secret) = &self.client_secret { + oauth_client = oauth_client.set_client_secret(ClientSecret::new(secret.clone())); + } + + let mut token_request = oauth_client .exchange_code(AuthorizationCode::new(code.to_string())); // For public clients, retrieve and use the PKCE verifier @@ -173,8 +188,7 @@ impl OidcClient { } } - // Create HTTP client for token exchange (oauth2 5.0 uses reqwest::Client directly) - // Note: For SSRF protection, consider using redirect::Policy::none() in production + // Create HTTP client for token exchange with redirect disabled for SSRF protection let oauth_http_client = Client::builder() .redirect(reqwest::redirect::Policy::none()) .build() @@ -220,4 +234,3 @@ pub struct OidcAuthResponse { pub email: Option, pub is_new_user: bool, } - diff --git a/src/routes/auth.rs b/src/routes/auth.rs index a4fbcbb..cf4ef18 100644 --- a/src/routes/auth.rs +++ b/src/routes/auth.rs @@ -197,8 +197,10 @@ async fn oidc_login(State(state): State>) -> Result