diff --git a/.gitignore b/.gitignore index 3667c10..9aa4231 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /data /.env +/result diff --git a/Cargo.lock b/Cargo.lock index 9d33213..76a6fbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aead" version = "0.5.2" @@ -14,9 +29,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", "cipher", @@ -25,9 +40,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", "aes", @@ -37,22 +52,11 @@ dependencies = [ "subtle", ] -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -74,29 +78,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", -] - -[[package]] -name = "attohttpc" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" -dependencies = [ - "http", - "log", - "rustls 0.20.8", - "serde", - "serde_json", - "url", - "webpki", - "webpki-roots", + "syn 2.0.38", ] [[package]] @@ -105,42 +93,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "aws-creds" -version = "0.34.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3776743bb68d4ad02ba30ba8f64373f1be4e082fe47651767171ce75bb2f6cf5" -dependencies = [ - "attohttpc", - "dirs", - "log", - "quick-xml", - "rust-ini", - "serde", - "thiserror", - "time", - "url", -] - -[[package]] -name = "aws-region" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "056557a61427d0e5ba29dd931031c8ffed4ee7a550e7cd55692a9d8deb0a9dba" -dependencies = [ - "thiserror", -] - [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", "axum-macros", - "bitflags", + "bitflags 1.3.2", "bytes", "futures-util", "headers", @@ -184,9 +146,9 @@ dependencies = [ [[package]] name = "axum-extra" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "febf23ab04509bd7672e6abe76bd8277af31b679e89fa5ffc6087dc289a448a3" +checksum = "a93e433be9382c737320af3924f7d5fc6f89c155cf2bf88949d8f5126fab283f" dependencies = [ "axum", "axum-core", @@ -200,43 +162,60 @@ dependencies = [ "serde", "tokio", "tower", - "tower-http", "tower-layer", "tower-service", ] [[package]] name = "axum-macros" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb524613be645939e280b7279f7b017f98cf7f5ef084ec374df373530e73277" +checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "axum_oidc" version = "0.1.0" -source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#29689243f487207da6d5ce5bfa3e3548ca14a4da" +source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#89da8cc07fba48a9adcd5821fbc7c527c60ec802" dependencies = [ "async-trait", "axum", "axum-extra", + "futures-util", + "jsonwebtoken", "openidconnect", "reqwest", "serde", "serde_json", "thiserror", + "tower", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -246,9 +225,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -262,19 +241,23 @@ version = "0.1.0" dependencies = [ "axum", "axum_oidc", + "bytes", + "chacha20", "dotenvy", + "env_logger", "futures-util", + "hex", "log", "markdown", - "pretty_env_logger", + "pin-project-lite", "rand", "render", - "rust-s3", "serde", - "serde_cbor", + "sha3", "thiserror", "tokio", "tokio-util", + "toml", ] [[package]] @@ -283,6 +266,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "block-buffer" version = "0.10.4" @@ -294,27 +283,30 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -323,16 +315,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.26" +name = "chacha20" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", - "winapi", + "wasm-bindgen", + "windows-targets", ] [[package]] @@ -347,9 +352,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cookie" @@ -358,7 +363,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ "aes-gcm", - "base64 0.21.2", + "base64 0.21.4", "percent-encoding", "rand", "subtle", @@ -366,6 +371,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -374,18 +389,18 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.4.9" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core", @@ -414,10 +429,38 @@ dependencies = [ ] [[package]] -name = "darling" -version = "0.13.4" +name = "curve25519-dalek" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -425,40 +468,50 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.4" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "darling_macro" -version = "0.13.4" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "pem-rfc7468", "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "digest" version = "0.10.7" @@ -471,32 +524,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - [[package]] name = "dotenvy" version = "0.15.7" @@ -505,37 +532,61 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest", "elliptic-curve", "rfc6979", "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", ] [[package]] -name = "either" -version = "1.8.1" +name = "ed25519-dalek" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", "digest", "ff", "generic-array", @@ -551,9 +602,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -572,36 +623,37 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core", "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" + [[package]] name = "fnv" version = "1.0.7" @@ -617,21 +669,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.28" @@ -639,7 +676,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -648,17 +684,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" -[[package]] -name = "futures-executor" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.28" @@ -673,7 +698,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] @@ -694,11 +719,9 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", - "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -714,6 +737,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -740,10 +764,16 @@ dependencies = [ ] [[package]] -name = "group" -version = "0.12.1" +name = "gimli" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core", @@ -752,9 +782,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -762,36 +792,32 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] + +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags", + "base64 0.21.4", "bytes", "headers-core", "http", @@ -817,18 +843,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -876,12 +893,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - [[package]] name = "httparse" version = "1.8.0" @@ -890,9 +901,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -902,9 +913,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -917,7 +928,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -926,29 +937,30 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.21.1", + "rustls", "tokio", "tokio-rustls", ] [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -983,7 +995,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.1", + "serde", ] [[package]] @@ -995,31 +1019,19 @@ dependencies = [ "generic-array", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys", -] - [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", + "hermit-abi", "rustix", "windows-sys", ] @@ -1035,19 +1047,42 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.4", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1059,27 +1094,27 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1087,9 +1122,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.18" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "markdown" @@ -1104,32 +1139,15 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" - -[[package]] -name = "maybe-async" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "mime" @@ -1138,12 +1156,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] -name = "minidom" -version = "0.15.2" +name = "miniz_oxide" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f45614075738ce1b77a1768912a60c0227525971b03e09122a05b8a34a2a6278" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ - "rxml", + "adler", ] [[package]] @@ -1158,10 +1176,21 @@ dependencies = [ ] [[package]] -name = "num-bigint-dig" -version = "0.8.2" +name = "num-bigint" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" dependencies = [ "byteorder", "lazy_static", @@ -1197,9 +1226,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", @@ -1207,19 +1236,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] [[package]] name = "oauth2" -version = "4.4.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a6e2a2b13a56ebeabba9142f911745be6456163fd6c3d361274ebcd891a80c" +checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" dependencies = [ "base64 0.13.1", "chrono", @@ -1235,6 +1264,15 @@ dependencies = [ "url", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1249,13 +1287,14 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openidconnect" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a5d6209b4c67f07ec48ca5329cc68eb229ba1b856152d5688962110de7e286" +checksum = "62d6050f6a84b81f23c569f5607ad883293e57491036e318fafe6fc4895fadb1" dependencies = [ "base64 0.13.1", "chrono", "dyn-clone", + "ed25519-dalek", "hmac", "http", "itertools", @@ -1280,42 +1319,34 @@ dependencies = [ [[package]] name = "ordered-float" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" dependencies = [ "num-traits", ] -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown", -] - [[package]] name = "p256" -version = "0.11.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2", ] [[package]] name = "p384" -version = "0.11.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2", ] @@ -1331,22 +1362,31 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets", ] [[package]] -name = "pem-rfc7468" -version = "0.6.0" +name = "pem" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] @@ -1359,29 +1399,29 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1397,31 +1437,36 @@ checksum = "d15b6607fa632996eb8a17c9041cb6071cb75ac057abd45dece578723ea8c7c0" [[package]] name = "pkcs1" -version = "0.4.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ "der", "pkcs8", "spki", - "zeroize", ] [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", ] [[package]] -name = "polyval" -version = "0.6.0" +name = "platforms" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" dependencies = [ "cfg-if", "cpufeatures", @@ -1429,6 +1474,12 @@ dependencies = [ "universal-hash", ] +[[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.17" @@ -1436,13 +1487,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "pretty_env_logger" -version = "0.5.0" +name = "primeorder" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" +checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" dependencies = [ - "env_logger", - "log", + "elliptic-curve", ] [[package]] @@ -1471,28 +1521,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] -[[package]] -name = "quick-xml" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1529,38 +1569,30 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall 0.2.16", - "thiserror", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -1569,9 +1601,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "render" @@ -1594,11 +1626,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -1615,19 +1647,18 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.1", + "rustls", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-rustls", - "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", "web-sys", "webpki-roots", "winreg", @@ -1635,13 +1666,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] @@ -1661,11 +1691,12 @@ dependencies = [ [[package]] name = "rsa" -version = "0.7.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ "byteorder", + "const-oid", "digest", "num-bigint-dig", "num-integer", @@ -1675,63 +1706,34 @@ dependencies = [ "pkcs8", "rand_core", "signature", - "smallvec", + "spki", "subtle", "zeroize", ] [[package]] -name = "rust-ini" -version = "0.18.0" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] -name = "rust-s3" -version = "0.33.0" +name = "rustc_version" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2ac5ff6acfbe74226fa701b5ef793aaa054055c13ebb7060ad36942956e027" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "async-trait", - "aws-creds", - "aws-region", - "base64 0.13.1", - "bytes", - "cfg-if", - "futures", - "hex", - "hmac", - "http", - "log", - "maybe-async", - "md5", - "minidom", - "percent-encoding", - "quick-xml", - "reqwest", - "serde", - "serde_derive", - "sha2", - "thiserror", - "time", - "tokio", - "tokio-stream", - "url", + "semver", ] [[package]] name = "rustix" -version = "0.37.19" +version = "0.38.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" dependencies = [ - "bitflags", + "bitflags 2.4.1", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -1739,21 +1741,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" -dependencies = [ - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -1763,18 +1753,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ "ring", "untrusted", @@ -1782,38 +1772,21 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" - -[[package]] -name = "rxml" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98f186c7a2f3abbffb802984b7f1dfd65dac8be1aafdaabbca4137f53f0dff7" -dependencies = [ - "bytes", - "rxml_validation", - "smartstring", -] - -[[package]] -name = "rxml_validation" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -1827,9 +1800,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1840,10 +1813,16 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.164" +name = "semver" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] @@ -1858,32 +1837,22 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1892,18 +1861,28 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ + "itoa", "serde", ] [[package]] name = "serde_plain" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -1922,31 +1901,38 @@ dependencies = [ [[package]] name = "serde_with" -version = "1.14.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ + "base64 0.21.4", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.0.2", "serde", + "serde_json", "serde_with_macros", + "time", ] [[package]] name = "serde_with_macros" -version = "1.5.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -1955,15 +1941,25 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1975,39 +1971,40 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest", "rand_core", ] [[package]] -name = "slab" -version = "0.4.8" +name = "simple_asn1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "smartstring" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" -dependencies = [ - "autocfg", - "static_assertions", - "version_check", -] +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "socket2" @@ -2019,6 +2016,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spin" version = "0.5.2" @@ -2027,20 +2034,14 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.10.0" @@ -2066,9 +2067,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -2082,41 +2083,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] -name = "termcolor" -version = "1.2.0" +name = "system-configuration" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "termcolor" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "time" -version = "0.3.22" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ + "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -2124,15 +2148,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -2154,11 +2178,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -2166,7 +2190,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.4", "tokio-macros", "windows-sys", ] @@ -2179,7 +2203,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] @@ -2188,26 +2212,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.1", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" -dependencies = [ - "futures-core", - "pin-project-lite", + "rustls", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -2217,6 +2230,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.0.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -2233,24 +2280,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower-layer", - "tower-service", -] - [[package]] name = "tower-layer" version = "0.3.2" @@ -2265,11 +2294,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-core", @@ -2277,9 +2305,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -2292,9 +2320,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" @@ -2304,9 +2332,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -2335,9 +2363,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -2353,11 +2381,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -2369,9 +2396,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2379,24 +2406,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -2406,9 +2433,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2416,64 +2443,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" - -[[package]] -name = "wasm-streams" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "winapi" @@ -2493,9 +2494,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -2507,10 +2508,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ "windows-targets", ] @@ -2526,9 +2527,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -2541,53 +2542,63 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +dependencies = [ + "memchr", +] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c147904..9d77969 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,18 +6,23 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "1.27.0", features = ["full"] } -tokio-util = { version="0.7"} +tokio = { version = "1.33", features = ["full"] } +tokio-util = { version="0.7", features = ["io"]} futures-util = "0.3" axum = {version="0.6", features=["macros", "headers"]} serde = "1.0" -serde_cbor = "0.11" +toml = "0.8" render = { git="https://github.com/render-rs/render.rs" } -thiserror = "1.0.40" -rand = "0.8.5" +thiserror = "1.0" +rand = "0.8" dotenvy = "0.15" -markdown = "0.3.0" +markdown = "0.3" axum_oidc = {git="https://git2.zettoit.eu/pfz4/axum_oidc"} -rust-s3 = { version="0.33.0", features=["tokio-rustls-tls", "tags"], default_features=false } -log = "0.4.18" -pretty_env_logger = "0.5.0" +log = "0.4" +env_logger = "0.10" + +chacha20 = "0.9" +sha3 = "0.10" +hex = "0.4" +bytes = "1.5" +pin-project-lite = "0.2" diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index fe076b4..0000000 --- a/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM debian:stable-slim as final -WORKDIR /app -COPY ./target/release/bin ./bin -CMD ["/app/bin"] diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..8f049e7 --- /dev/null +++ b/flake.lock @@ -0,0 +1,129 @@ +{ + "nodes": { + "crane": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": [ + "rust-overlay" + ] + }, + "locked": { + "lastModified": 1697513493, + "narHash": "sha256-Kjidf29+ahcsQE7DICxI4g4tjMSY76BfhKFANnkQhk0=", + "owner": "ipetkov", + "repo": "crane", + "rev": "eb5034b6ee36d523bf1d326ab990811ac2ceb870", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696267196, + "narHash": "sha256-AAQ/2sD+0D18bb8hKuEEVpHUYD1GmO2Uh/taFamn6XQ=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "4f910c9827911b1ec2bf26b5a062cd09f8d89f85", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1697059129, + "narHash": "sha256-9NJcFF9CEYPvHJ5ckE8kvINvI84SZZ87PvqMbH6pro0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5e4c2ada4fcd54b99d56d7bd62f384511a7e2593", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1697508761, + "narHash": "sha256-QKWiXUlnke+EiJw3pek1l7xyJ4YsxYXZeQJt/YLgjvA=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "6f74c92caaf2541641b50ec623676430101d1fd4", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..6bfd7f7 --- /dev/null +++ b/flake.nix @@ -0,0 +1,69 @@ +{ + description = "bin service"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + crane = { + url = "github:ipetkov/crane"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + rust-overlay.follows = "rust-overlay"; + }; + }; + }; + + outputs = { self, nixpkgs, flake-utils, rust-overlay, crane}: + flake-utils.lib.eachDefaultSystem (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { + inherit system overlays; + }; + + rustToolchain = pkgs.rust-bin.stable.latest.default; + + markdownFilter = path: _type: builtins.match ".*md$" path != null; + markdownOrCargo = path: type: (markdownFilter path type) || (craneLib.filterCargoSources path type); + + craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain; + src = pkgs.lib.cleanSourceWith { + src = craneLib.path ./.; + filter = markdownOrCargo; + }; + + nativeBuildInputs = with pkgs; [ rustToolchain pkg-config ]; + buildInputs = with pkgs; [ ]; + + commonArgs = { + inherit src buildInputs nativeBuildInputs; + }; + cargoArtifacts = craneLib.buildDepsOnly commonArgs; + + bin = craneLib.buildPackage (commonArgs // { + inherit cargoArtifacts; + }); + + in + with pkgs; + { + packages = { + inherit bin; + default = bin; + }; + devShells.default = mkShell { + inputsFrom = [ bin ]; + }; + + hydraJobs."build" = bin; + } + ); +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..ae01186 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,45 @@ +use axum::{http::StatusCode, response::IntoResponse}; +use log::error; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("io error: {:?}", 0)] + Io(#[from] std::io::Error), + #[error("time error: {:?}", 0)] + Time(#[from] std::time::SystemTimeError), + #[error("metadata error: {:?}", 0)] + MetadataDe(#[from] toml::de::Error), + #[error("metadata error: {:?}", 0)] + MetadataSer(#[from] toml::ser::Error), + #[error("phrase is not valid")] + PhraseInvalid, + #[error("bin could not be found")] + BinNotFound, + #[error("file exists")] + DataFileExists, + + #[error("hex error: {:?}", 0)] + Hex(#[from] hex::FromHexError), + + #[error("could not parse ttl")] + ParseTtl, + + #[error("encryption error")] + ChaCha, +} + +impl IntoResponse for Error { + fn into_response(self) -> axum::response::Response { + match self { + Self::PhraseInvalid => (StatusCode::BAD_REQUEST, "phrase is not valid"), + Self::BinNotFound => (StatusCode::NOT_FOUND, "bin does not exist"), + Self::DataFileExists => (StatusCode::CONFLICT, "bin already has data"), + Self::ParseTtl => (StatusCode::BAD_REQUEST, "invalid ttl class"), + _ => { + error!("{:?}", self); + (StatusCode::INTERNAL_SERVER_ERROR, "internal server error") + } + } + .into_response() + } +} diff --git a/src/garbage_collector.rs b/src/garbage_collector.rs new file mode 100644 index 0000000..9b6d928 --- /dev/null +++ b/src/garbage_collector.rs @@ -0,0 +1,108 @@ +use std::{ + collections::BinaryHeap, + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + +use log::{debug, info, warn}; +use tokio::{fs, sync::Mutex}; + +use crate::{metadata::Metadata, util::Id}; + +#[derive(Clone)] +pub(crate) struct GarbageCollector { + heap: Arc>>, + path: String, +} + +impl GarbageCollector { + pub(crate) async fn new(path: String) -> Self { + let mut heap = BinaryHeap::new(); + let mut dir = fs::read_dir(&path).await.expect("readable data dir"); + while let Ok(Some(entry)) = dir.next_entry().await { + let file_name = entry.file_name(); + let file_name = file_name.to_string_lossy(); + if let Some(id) = file_name.strip_suffix(".toml") { + if let Ok(metadata) = Metadata::from_file(&format!("./data/{}.toml", id)).await { + heap.push(GarbageCollectorItem { + expires_at: metadata.expires_at, + id: Id::from_str(id), + }) + } + } + } + Self { + heap: Arc::new(Mutex::new(heap)), + path, + } + } + + pub(crate) async fn schedule(&self, id: &Id, expires_at: u64) { + self.heap.lock().await.push(GarbageCollectorItem { + id: id.clone(), + expires_at, + }) + } + + pub(crate) async fn run(&self) { + let mut heap = self.heap.lock().await; + + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("time after EPOCH") + .as_secs(); + + // skip if first item is not old enough to be deleted + if let Some(true) = heap.peek().map(|x| x.expires_at > now) { + return; + } + if let Some(item) = heap.pop() { + if let Ok(metadata) = + Metadata::from_file(&format!("{}/{}.toml", self.path, item.id)).await + { + // check metadata if the item is really ready for deletion (needed for reschedule + // population of bin with data) + if metadata.expires_at <= now { + debug!("deleting bin {}", item.id); + let res_meta = + fs::remove_file(&format!("{}/{}.toml", self.path, item.id)).await; + let res_data = fs::remove_file(&format!("{}/{}.dat", self.path, item.id)).await; + + if res_meta.is_err() || res_data.is_err() { + warn!("failed to delete bin {} for gc", item.id); + } + } + } else { + info!("cant open metadata file for bin {} for gc", item.id); + } + } + } + + pub(crate) fn spawn(&self) { + let gc = self.clone(); + tokio::spawn(async move { + loop { + tokio::time::sleep(Duration::from_secs(10)).await; + gc.run().await; + } + }); + } +} + +#[derive(PartialEq, Eq)] +struct GarbageCollectorItem { + id: Id, + expires_at: u64, +} + +impl PartialOrd for GarbageCollectorItem { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for GarbageCollectorItem { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.expires_at.cmp(&other.expires_at).reverse() + } +} diff --git a/src/item_explanation.md b/src/item_explanation.md index 52043a2..d0c2d47 100644 --- a/src/item_explanation.md +++ b/src/item_explanation.md @@ -2,9 +2,7 @@ An empty bin was created for you. The first HTTP POST or PUT request can upload data. All following requests can only read the uploaded data. -To use the build-in link-shortener functionality you have to POST or PUT the URL with Content-Type: text/x-uri or Content-Type: text/uri-list. - -To change the default expiration date, you can use the `?ttl=` parameter. The following expiry classes are defined: . +To change the default expiration date, you can use the `?ttl=` parameter. ## Upload a link `$ curl -H "Content-Type: text/x-uri" --data "https://example.com" ` @@ -27,4 +25,3 @@ $ curl | gpg -d - | tar -xzf ## Accessing the data After uploading data you can access it by accessing with an optional file extension that suits the data that you uploaded. -If the bin is a link you will get redirected. diff --git a/src/main.rs b/src/main.rs index c3e4bef..480f8fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,13 @@ +#![deny(clippy::unwrap_used)] use std::{ - collections::HashSet, + borrow::Borrow, env, - io::ErrorKind, - task::{Context, Poll}, - time::Duration, + str::FromStr, + time::{SystemTime, UNIX_EPOCH}, }; use axum::{ - body::{Bytes, StreamBody}, + body::StreamBody, debug_handler, extract::{BodyStream, FromRef, Path, Query, State}, headers::ContentType, @@ -16,62 +16,49 @@ use axum::{ routing::get, Router, TypedHeader, }; -use axum_oidc::{ClaimsExtractor, EmptyAdditionalClaims, Key, OidcApplication}; -use futures_util::{Stream, StreamExt, TryStreamExt}; -use log::{info, warn}; -use rand::{distributions::Alphanumeric, Rng}; +use axum_oidc::oidc::{self, EmptyAdditionalClaims, OidcApplication, OidcExtractor}; +use chacha20::{ + cipher::{KeyIvInit, StreamCipher}, + ChaCha20, +}; +use futures_util::StreamExt; +use garbage_collector::GarbageCollector; +use log::debug; use render::{html, raw}; -use s3::{creds::Credentials, error::S3Error, request::ResponseDataStream, Bucket}; use serde::Deserialize; -use tokio_util::io::StreamReader; +use sha3::{Digest, Sha3_256}; +use tokio::{ + fs::File, + io::{AsyncWriteExt, BufReader, BufWriter}, +}; +use util::{IdSalt, KeySalt}; -// RFC 7230 section 3.1.1 -// It is RECOMMENDED that all HTTP senders and recipients -// support, at a minimum, request-line lengths of 8000 octets. -const HTTP_URL_MAXLENGTH: i64 = 8000; +use crate::{ + error::Error, + metadata::Metadata, + util::{Id, Key, Nonce, Phrase}, + web_util::DecryptingStream, +}; +mod error; +mod garbage_collector; +mod metadata; +mod util; +mod web_util; -// support the RFC2483 with text/uri-list and the inofficial text/x-uri mimetype -const HTTP_URL_MIMETYPES: [&str; 2] = ["text/x-uri", "text/uri-list"]; +/// length of the "phrase" that is used to access the bin (https://example.com/) +const PHRASE_LENGTH: usize = 16; +/// length of the salts that are used to generate the key for chacha and id for the files +const SALT_LENGTH: usize = 256 - PHRASE_LENGTH; -#[derive(Debug, thiserror::Error)] -enum Error { - #[error("s3 error: {:?}", 1)] - S3(#[from] S3Error), - #[error("url is invalid utf8")] - UrlUtf8Invalid, - #[error("item could not be found")] - ItemNotFound, - #[error("file exists")] - DataFileExists, - - #[error("could not parse ttl")] - ParseTtl, -} type HandlerResult = Result; - -impl IntoResponse for Error { - fn into_response(self) -> axum::response::Response { - match self { - Self::S3(e) => { - warn!("S3 Error: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "s3 error") - } - Self::UrlUtf8Invalid => (StatusCode::INTERNAL_SERVER_ERROR, "url is not valid utf8"), - Self::ItemNotFound => (StatusCode::NOT_FOUND, "bin could not be found"), - Self::DataFileExists => (StatusCode::CONFLICT, "bin already has data"), - Self::ParseTtl => (StatusCode::BAD_REQUEST, "invalid ttl class"), - } - .into_response() - } -} - #[derive(Clone)] pub struct AppState { application_base: String, oidc_application: OidcApplication, - bucket: Bucket, - lifecycle_classes: HashSet, - default_lifecycle_class: String, + data: String, + key_salt: KeySalt, + id_salt: IdSalt, + garbage_collector: GarbageCollector, } impl FromRef for OidcApplication { @@ -80,10 +67,16 @@ impl FromRef for OidcApplication { } } +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct ExpiryHeapItem { + pub expires_at: u64, + pub id: String, +} + #[tokio::main] async fn main() { dotenvy::dotenv().ok(); - pretty_env_logger::init(); + env_logger::init(); let application_base = env::var("APPLICATION_BASE").expect("APPLICATION_BASE env var"); let issuer = env::var("ISSUER").expect("ISSUER env var"); @@ -96,204 +89,167 @@ async fn main() { .collect::>(); let oidc_application = OidcApplication::::create( - application_base.parse().unwrap(), + application_base + .parse() + .expect("valid APPLICATION_BASE url"), issuer.to_string(), client_id.to_string(), client_secret.to_owned(), scopes.clone(), - Key::generate(), + oidc::Key::generate(), ) .await - .unwrap(); + .expect("Oidc Authentication Client"); - let bucket = Bucket::new( - &env::var("S3_BUCKET").expect("S3_BUCKET env var"), - env::var("S3_REGION") - .expect("S3_REGION env var") - .parse() - .unwrap(), - Credentials::new( - Some(&env::var("S3_ACCESS_KEY").expect("S3_ACCESS_KEY env var")), - Some(&env::var("S3_SECRET_KEY").expect("S3_SECRET_KEY env var")), - None, - None, - None, - ) - .unwrap(), - ) - .unwrap() - .with_path_style() - .with_request_timeout(Duration::from_secs(60 * 60 * 6)); - - let lifecycle_classes = std::env::var("LIFECYCLE_CLASSES") - .expect("LIFECYCLE_CLASSES env var") - .split(',') - .map(|x| x.to_string()) - .collect::>(); - let default_lifecycle_class = - std::env::var("DEFAULT_LIFECYCLE_CLASS").expect("DEFAULT_LIFECYCLE_CLASS env var"); - if !lifecycle_classes.contains(&default_lifecycle_class) { - panic!("DEFAULT_LIFECYCLE_CLASS must be an element of LIFECYCLE_CLASSES"); - } + let garbage_collector = GarbageCollector::new("./data".to_string()).await; + garbage_collector.spawn(); let state: AppState = AppState { application_base, oidc_application, - bucket, - lifecycle_classes, - default_lifecycle_class, + data: "./data".to_string(), + key_salt: KeySalt::from_str(&env::var("KEY_SALT").expect("KEY_SALT env var")) + .expect("KEY SALT valid hex"), + id_salt: IdSalt::from_str(&env::var("ID_SALT").expect("ID_SALT env var")) + .expect("ID_SALT valid hex"), + garbage_collector, }; + // when the two salts are identical, the bin id and the bin key are also identical, this would + // make the encryption useless + assert_ne!(state.key_salt.raw(), state.id_salt.raw()); + let app = Router::new() .route("/", get(get_index)) .route("/:id", get(get_item).post(post_item).put(post_item)) .with_state(state); - axum::Server::bind(&"[::]:3000".parse().unwrap()) + axum::Server::bind(&"[::]:8080".parse().expect("valid listen address")) .serve(app.into_make_service()) .await - .unwrap(); + .expect("Axum Server"); } async fn get_index( State(app_state): State, - ClaimsExtractor(claims): ClaimsExtractor, + OidcExtractor { claims, .. }: OidcExtractor, ) -> Result { let subject = claims.subject().to_string(); - //generate id - let id = rand::thread_rng() - .sample_iter(Alphanumeric) - .take(8) - .map(char::from) - .collect::(); + //generate phrase and derive id from it + let phrase = Phrase::random(); + let id = Id::from_phrase(&phrase, &app_state.id_salt); - app_state.bucket.put_object(&id, &[]).await?; - app_state - .bucket - .put_object_tagging( - &id, - &[ - ("ttl".to_string(), app_state.default_lifecycle_class.clone()), - ("subject".to_string(), subject), - ], - ) - .await?; + let nonce = Nonce::random(); - info!("created bin {id}"); + let expires_at = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() + 24 * 3600; + + let metadata_path = format!("{}/{}.toml", app_state.data, id); + let metadata = Metadata { + subject, + nonce: nonce.to_hex(), + etag: None, + size: None, + content_type: None, + expires_at, + }; + metadata.to_file(&metadata_path).await?; + + app_state.garbage_collector.schedule(&id, expires_at).await; + + debug!("created bin {id}"); Ok(Redirect::temporary(&format!( "{}{}", - app_state.application_base, id + app_state.application_base, phrase ))) } #[derive(Deserialize)] pub struct PostQuery { - ttl: Option, + ttl: Option, } async fn post_item( - Path(id): Path, + Path(phrase): Path, Query(params): Query, State(app_state): State, content_type: Option>, - stream: BodyStream, + mut stream: BodyStream, ) -> HandlerResult { - let id = sanitize_id(id); + let phrase = Phrase::from_str(&phrase)?; + let id = Id::from_phrase(&phrase, &app_state.id_salt); - let metadata = app_state.bucket.head_object(&id).await?.0; + let metadata_path = format!("{}/{}.toml", app_state.data, id); + let mut metadata = Metadata::from_file(&metadata_path).await?; - if metadata.e_tag.is_none() { - return Err(Error::ItemNotFound); - } - if let Some(content_length) = metadata.content_length { - if content_length > 0 { - return Err(Error::DataFileExists); + let path = format!("{}/{}.dat", app_state.data, id); + let path = std::path::Path::new(&path); + + if !path.exists() { + let key = Key::from_phrase(&phrase, &app_state.key_salt); + let nonce = Nonce::from_hex(&metadata.nonce)?; + let mut cipher = ChaCha20::new(key.borrow(), nonce.borrow()); + + let file = File::create(&path).await?; + let mut writer = BufWriter::new(file); + + let mut etag_hasher = Sha3_256::new(); + let mut size = 0; + + while let Some(chunk) = stream.next().await { + let mut buf = chunk.unwrap_or_default().to_vec(); + etag_hasher.update(&buf); + size += buf.len() as u64; + cipher.apply_keystream(&mut buf); + writer.write_all(&buf).await?; } - } - let ttl = if let Some(ttl) = ¶ms.ttl { - if !app_state.lifecycle_classes.contains(ttl) { - return Err(Error::ParseTtl); - } - ttl + writer.flush().await?; + + metadata.etag = Some(hex::encode(etag_hasher.finalize())); + metadata.size = Some(size); + metadata.content_type = match content_type { + Some(content_type) => Some(content_type.to_string()), + None => Some("application/octet-stream".to_string()), + }; + metadata.expires_at = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() + + params.ttl.unwrap_or(24 * 3600); + metadata.to_file(&metadata_path).await?; + + app_state + .garbage_collector + .schedule(&id, metadata.expires_at) + .await; + + debug!("bin {id} got filled"); + + Ok((StatusCode::OK, "ok\n")) } else { - &app_state.default_lifecycle_class - }; - - let tags = app_state.bucket.get_object_tagging(&id).await?.0; - - let mut reader = - StreamReader::new(stream.map_err(|e| std::io::Error::new(ErrorKind::Other, e.to_string()))); - let status_code = match content_type { - Some(content_type) => { - app_state - .bucket - .put_object_stream_with_content_type(&mut reader, &id, &content_type.to_string()) - .await - } - None => app_state.bucket.put_object_stream(&mut reader, &id).await, - }?; - - let status_code = StatusCode::from_u16(status_code).unwrap(); - - let subject = tags - .iter() - .find(|x| x.key() == "subject") - .map(|x| x.value()) - .unwrap_or_default(); - - app_state - .bucket - .put_object_tagging( - &id, - &[ - ("ttl".to_string(), ttl.to_string()), - ("subject".to_string(), subject), - ], - ) - .await?; - - info!("bin {id} is now read only"); - - Ok(( - status_code, - format!( - "{}\n", - status_code - .canonical_reason() - .unwrap_or(&status_code.to_string()) - ), - )) + Err(Error::DataFileExists) + } } #[debug_handler] async fn get_item( - Path(id): Path, + Path(phrase): Path, State(app_state): State, ) -> HandlerResult { - let id = sanitize_id(id); + let phrase = Phrase::from_str(&phrase)?; + let id = Id::from_phrase(&phrase, &app_state.id_salt); - let metadata = app_state.bucket.head_object(&id).await?.0; + let metadata = Metadata::from_file(&format!("{}/{}.toml", app_state.data, id)).await?; + + let path = format!("{}/{}.dat", app_state.data, id); + + let key = Key::from_phrase(&phrase, &app_state.key_salt); + let nonce = Nonce::from_hex(&metadata.nonce)?; + + if std::fs::metadata(&path).is_err() { + let body = include_str!("item_explanation.md").replace( + "", + &format!("{}{}", app_state.application_base, phrase), + ); - if metadata.e_tag.is_none() { - return Err(Error::ItemNotFound); - } - if metadata.content_length.is_none() || metadata.content_length == Some(0) { - let body = include_str!("item_explanation.md") - .replace( - "", - &format!("{}{}", app_state.application_base, id), - ) - .replace( - "", - &app_state - .lifecycle_classes - .iter() - .map(|x| x.to_string()) - .reduce(|acc, e| acc + ", " + e.as_str()) - .unwrap_or_default(), - ); let body = markdown::to_html(&body); let body = html! { @@ -309,70 +265,32 @@ async fn get_item( }; Ok((StatusCode::ACCEPTED, Html(body)).into_response()) - } else if let Some(content_length) = metadata.content_length { - if HTTP_URL_MIMETYPES.contains(&metadata.content_type.as_deref().unwrap_or("")) - && content_length <= HTTP_URL_MAXLENGTH - { - let file = app_state.bucket.get_object(&id).await?; - let url = String::from_utf8(file.to_vec()).map_err(|_| Error::UrlUtf8Invalid)?; - - // Use the first line that doesn't start with a # to be compliant with RFC2483. - let url = url.lines().find(|x| !x.starts_with('#')).unwrap_or(""); - - Ok(Redirect::temporary(url).into_response()) - } else { - let file_stream = app_state.bucket.get_object_stream(&id).await.unwrap(); - - let body = StreamBody::new(ResponseStream(std::sync::Mutex::new(file_stream))); - - let mut headers = HeaderMap::new(); - headers.insert( - header::CONTENT_LENGTH, - metadata.content_length.unwrap().into(), - ); - - if let Some(content_type) = metadata.content_type { - headers.insert(header::CONTENT_TYPE, content_type.parse().unwrap()); - } - if let Some(etag) = metadata.e_tag { - headers.insert(header::ETAG, etag.parse().unwrap()); - } - if let Some(content_encoding) = metadata.content_encoding { - headers.insert(header::CONTENT_ENCODING, content_encoding.parse().unwrap()); - } - if let Some(content_language) = metadata.content_language { - headers.insert(header::CONTENT_LANGUAGE, content_language.parse().unwrap()); - } - if let Some(cache_control) = metadata.cache_control { - headers.insert(header::CACHE_CONTROL, cache_control.parse().unwrap()); - } - - Ok((StatusCode::OK, headers, body).into_response()) - } } else { - // logically should not happen - panic!("logic contradiction"); + //TODO(pfz4): Maybe add link handling + let file = File::open(&path).await?; + let reader = BufReader::new(file); + + let body = StreamBody::new(DecryptingStream::new(reader, id, &metadata, &key, &nonce)); + + let mut headers = HeaderMap::new(); + headers.insert( + header::CONTENT_LENGTH, + metadata.size.unwrap_or_default().into(), + ); + + if let Some(content_type) = metadata.content_type.and_then(|x| x.parse().ok()) { + headers.insert(header::CONTENT_TYPE, content_type); + } + if let Some(etag) = metadata.etag.clone().and_then(|x| x.parse().ok()) { + headers.insert(header::ETAG, etag); + } + if let Some(digest) = metadata + .etag + .and_then(|x| format!("sha3-256={x}").parse().ok()) + { + headers.insert("Digest", digest); + } + + Ok((StatusCode::OK, headers, body).into_response()) } } - -fn sanitize_id(id: String) -> String { - id.chars() - .take_while(|c| *c != '.') - .filter(|c| c.is_ascii_alphanumeric()) - .collect() -} - -struct ResponseStream(std::sync::Mutex); -impl Stream for ResponseStream { - type Item = Result; - - fn poll_next(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - self.0 - .lock() - .unwrap() - .bytes() - .poll_next_unpin(cx) - .map(|x| x.map(Ok)) - } -} -unsafe impl Send for ResponseStream {} diff --git a/src/metadata.rs b/src/metadata.rs new file mode 100644 index 0000000..2df9f70 --- /dev/null +++ b/src/metadata.rs @@ -0,0 +1,33 @@ +use std::{io::ErrorKind, time::Instant}; + +use serde::{Deserialize, Serialize}; +use tokio::{fs::File, io::AsyncWriteExt}; + +use crate::Error; + +#[derive(Deserialize, Serialize, Debug)] +pub struct Metadata { + pub subject: String, + pub nonce: String, + pub etag: Option, + pub size: Option, + pub content_type: Option, + pub expires_at: u64, // seconds since UNIX_EPOCH +} + +impl Metadata { + pub async fn from_file(path: &str) -> Result { + let metadata = match tokio::fs::read_to_string(path).await { + Ok(x) => Ok(x), + Err(err) if err.kind() == ErrorKind::NotFound => Err(Error::BinNotFound), + Err(x) => Err(x.into()), + }?; + Ok(toml::from_str::(&metadata)?) + } + pub async fn to_file(&self, path: &str) -> Result<(), Error> { + let data = toml::to_string(&self)?; + let mut file = File::create(path).await?; + file.write_all(data.as_ref()).await?; + Ok(()) + } +} diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..8e382ea --- /dev/null +++ b/src/util.rs @@ -0,0 +1,238 @@ +use std::{borrow::Borrow, fmt::Display, str::FromStr}; + +use chacha20::cipher::{generic_array::GenericArray, ArrayLength}; +use rand::{distributions, Rng}; +use sha3::{Digest, Sha3_256}; + +use crate::{error::Error, PHRASE_LENGTH, SALT_LENGTH}; + +#[derive(Debug, PartialEq)] +pub(crate) struct Phrase(String); +#[derive(Debug, PartialEq, Eq, Clone)] +pub(crate) struct Id(String); +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct IdSalt(Vec); +#[derive(Debug, PartialEq)] +pub(crate) struct Key(Vec); +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct KeySalt(Vec); +#[derive(Debug, PartialEq)] +pub(crate) struct Nonce(Vec); + +impl Phrase { + pub(crate) fn random() -> Self { + let phrase = rand::thread_rng() + .sample_iter(distributions::Alphanumeric) + .take(PHRASE_LENGTH) + .map(char::from) + .collect::(); + Self(phrase) + } +} +impl FromStr for Phrase { + type Err = Error; + + fn from_str(s: &str) -> Result { + if s.chars().any(|x| !x.is_ascii_alphanumeric()) { + Err(Error::PhraseInvalid) + } else { + Ok(Self(s.to_string())) + } + } +} +impl Display for Phrase { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl Id { + pub(crate) fn from_phrase(phrase: &Phrase, salt: &IdSalt) -> Self { + let mut hasher = Sha3_256::new(); + hasher.update(&phrase.0); + hasher.update(&salt.0); + + let id = hex::encode(hasher.finalize()); + Self(id) + } + pub(crate) fn from_str(s: &str) -> Self { + Self(s.to_string()) + } + pub(crate) fn raw(&self) -> &str { + &self.0 + } +} +impl Display for Id { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl IdSalt { + pub(crate) fn random() -> Self { + let salt = rand::thread_rng() + .sample_iter(distributions::Standard) + .take(SALT_LENGTH) + .collect(); + Self(salt) + } + pub(crate) fn raw(&self) -> &[u8] { + &self.0 + } +} +impl FromStr for IdSalt { + type Err = hex::FromHexError; + + fn from_str(s: &str) -> Result { + Ok(Self(hex::decode(s)?)) + } +} + +impl Key { + pub(crate) fn from_phrase(phrase: &Phrase, salt: &KeySalt) -> Self { + let mut hasher = Sha3_256::new(); + hasher.update(&phrase.0); + hasher.update(&salt.0); + Self(hasher.finalize().to_vec()) + } +} + +impl> Borrow> for Key { + fn borrow(&self) -> &GenericArray { + GenericArray::::from_slice(&self.0) + } +} + +impl KeySalt { + pub(crate) fn random() -> Self { + let salt = rand::thread_rng() + .sample_iter(distributions::Standard) + .take(SALT_LENGTH) + .collect(); + Self(salt) + } + pub(crate) fn raw(&self) -> &[u8] { + &self.0 + } +} +impl FromStr for KeySalt { + type Err = hex::FromHexError; + + fn from_str(s: &str) -> Result { + Ok(Self(hex::decode(s)?)) + } +} + +impl Nonce { + pub(crate) fn random() -> Self { + // generate a 12 byte / 96 bit nonce for chacha20 as defined in rfc7539 + let nonce = rand::thread_rng() + .sample_iter(distributions::Standard) + .take(12) + .collect(); + Self(nonce) + } + pub(crate) fn from_hex(hex_value: &str) -> Result { + Ok(Self(hex::decode(hex_value)?)) + } + pub(crate) fn to_hex(&self) -> String { + hex::encode(&self.0) + } +} + +impl> Borrow> for Nonce { + fn borrow(&self) -> &GenericArray { + GenericArray::from_slice(&self.0) + } +} + +#[cfg(test)] +mod test { + use crate::{ + util::{Id, IdSalt, Key, KeySalt, Nonce, Phrase}, + PHRASE_LENGTH, SALT_LENGTH, + }; + + #[test] + fn phrase() { + assert_eq!(PHRASE_LENGTH, Phrase::random().0.len()); + assert_ne!(Phrase::random(), Phrase::random()); + } + + #[test] + fn id() { + let phrase = Phrase::random(); + let salt = IdSalt::random(); + let phrase2 = Phrase::random(); + let salt2 = IdSalt::random(); + + assert_eq!( + Id::from_phrase(&phrase, &salt), + Id::from_phrase(&phrase, &salt) + ); + + assert_ne!( + Id::from_phrase(&phrase, &salt), + Id::from_phrase(&phrase, &salt2) + ); + + assert_ne!( + Id::from_phrase(&phrase, &salt), + Id::from_phrase(&phrase2, &salt) + ); + } + + #[test] + fn key() { + let phrase = Phrase::random(); + let salt = KeySalt::random(); + let phrase2 = Phrase::random(); + let salt2 = KeySalt::random(); + + assert_eq!( + Key::from_phrase(&phrase, &salt), + Key::from_phrase(&phrase, &salt) + ); + + assert_ne!( + Key::from_phrase(&phrase, &salt), + Key::from_phrase(&phrase, &salt2) + ); + + assert_ne!( + Key::from_phrase(&phrase, &salt), + Key::from_phrase(&phrase2, &salt) + ); + } + + #[test] + #[allow(clippy::unwrap_used)] + fn key_id_collision() { + let phrase = Phrase::random(); + let id_salt = IdSalt::random(); + let key_salt = KeySalt::random(); + + assert_ne!( + hex::decode(Id::from_phrase(&phrase, &id_salt).0).unwrap(), + Key::from_phrase(&phrase, &key_salt).0 + ); + } + + #[test] + fn id_salt() { + assert_eq!(SALT_LENGTH, IdSalt::random().0.len()); + assert_ne!(IdSalt::random(), IdSalt::random()); + } + + #[test] + fn key_salt() { + assert_eq!(SALT_LENGTH, KeySalt::random().0.len()); + assert_ne!(KeySalt::random(), KeySalt::random()); + } + + #[test] + fn nonce() { + assert_eq!(12, Nonce::random().0.len()); + assert_ne!(Nonce::random(), Nonce::random()); + } +} diff --git a/src/web_util.rs b/src/web_util.rs new file mode 100644 index 0000000..1ecc505 --- /dev/null +++ b/src/web_util.rs @@ -0,0 +1,133 @@ +use std::{ + borrow::Borrow, + pin::Pin, + task::{Context, Poll}, +}; + +use bytes::{Bytes, BytesMut}; +use chacha20::{ + cipher::{KeyIvInit, StreamCipher}, + ChaCha20, +}; +use futures_util::Stream; +use log::{debug, warn}; +use pin_project_lite::pin_project; +use sha3::{Digest, Sha3_256}; +use tokio::io::AsyncRead; +use tokio_util::io::poll_read_buf; + +use crate::{ + metadata::Metadata, + util::{Id, Key, Nonce}, +}; +pin_project! { + pub(crate) struct DecryptingStream { + #[pin] + reader: Option, + buf: BytesMut, + // chunk size + capacity: usize, + // chacha20 cipher + cipher: ChaCha20, + // hasher to verify file integrity + hasher: Sha3_256, + // hash to verify against + target_hash: String, + // id of the file for logging purposes + id: Id, + // total file size + size: u64, + // current position of the "reading head" + progress: u64 + } +} +impl DecryptingStream { + pub(crate) fn new(reader: R, id: Id, metadata: &Metadata, key: &Key, nonce: &Nonce) -> Self { + let cipher = ChaCha20::new(key.borrow(), nonce.borrow()); + Self { + reader: Some(reader), + buf: BytesMut::new(), + capacity: 1 << 22, // 4 MiB + cipher, + hasher: Sha3_256::new(), + target_hash: metadata.etag.clone().unwrap_or_default(), + id, + size: metadata.size.unwrap_or_default(), + progress: 0, + } + } +} + +impl Stream for DecryptingStream { + type Item = std::io::Result; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.as_mut().project(); + + let reader = match this.reader.as_pin_mut() { + Some(r) => r, + None => return Poll::Ready(None), + }; + + if this.buf.capacity() == 0 { + this.buf.reserve(*this.capacity); + } + + match poll_read_buf(reader, cx, &mut this.buf) { + Poll::Pending => Poll::Pending, + Poll::Ready(Err(err)) => { + debug!("failed to send bin {}", this.id); + self.project().reader.set(None); + Poll::Ready(Some(Err(err))) + } + Poll::Ready(Ok(0)) => { + if self.progress_check() == DecryptingStreamProgress::Failed { + // The hash is invalid, the file has been tampered with. Close reader and stream causing the download to fail + self.project().reader.set(None); + return Poll::Ready(None); + }; + self.project().reader.set(None); + Poll::Ready(None) + } + Poll::Ready(Ok(n)) => { + let mut chunk = this.buf.split(); + // decrypt the chunk using chacha + this.cipher.apply_keystream(&mut chunk); + // update the sha3 hasher + this.hasher.update(&chunk); + // track progress + *this.progress += n as u64; + if self.progress_check() == DecryptingStreamProgress::Failed { + // The hash is invalid, the file has been tampered with. Close reader and stream causing the download to fail + warn!("bin {} is corrupted! transmission failed", self.id); + self.project().reader.set(None); + return Poll::Ready(None); + }; + Poll::Ready(Some(Ok(chunk.freeze()))) + } + } + } +} + +impl DecryptingStream { + /// checks if the hash is correct when the last byte has been read + fn progress_check(&self) -> DecryptingStreamProgress { + if self.progress >= self.size { + let hash = hex::encode(self.hasher.clone().finalize()); + if hash != self.target_hash { + DecryptingStreamProgress::Failed + } else { + DecryptingStreamProgress::Finished + } + } else { + DecryptingStreamProgress::Running + } + } +} + +#[derive(PartialEq, Eq)] +enum DecryptingStreamProgress { + Finished, + Failed, + Running, +}