diff --git a/.gitignore b/.gitignore index d94fb8b..9fdc579 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ **/target **/.direnv -fs/chunks +/chunks **/data.db* **/output.log diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5fc5fdd..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rust-analyzer.linkedProjects": [ - "./cli/Cargo.toml" - ] -} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index fa7e84d..ec84129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,72 +55,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" -[[package]] -name = "anstream" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "anstyle-parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" -dependencies = [ - "anstyle", - "windows-sys", -] - [[package]] name = "anyhow" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" -[[package]] -name = "argon2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ba4cac0a46bc1d2912652a751c47f2a9f3a7fe89bcae2275d418f5270402f9" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", -] - [[package]] name = "arrayref" version = "0.3.7" @@ -153,91 +93,12 @@ dependencies = [ "num-traits", ] -[[package]] -name = "auth" -version = "0.1.0" -dependencies = [ - "anyhow", - "argon2", - "axum", - "axum-macros", - "bfsp", - "fern", - "humantime", - "log", - "macaroon", - "rand", - "sqlx", - "tokio", -] - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-macros" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "backtrace" version = "0.3.69" @@ -274,11 +135,14 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bfsp" version = "0.1.0" +source = "git+https://github.com/Billy-s-E2EE-File-Server/bfsp#6b3079730a42c5fda4e03a5b752d061081afd89d" dependencies = [ "anyhow", "blake3", "bytes", "chacha20poly1305", + "directories", + "log", "macaroon", "prost", "prost-build", @@ -286,7 +150,9 @@ dependencies = [ "serde", "serde_derive", "sqlx", + "thiserror", "tokio", + "toml", "uuid", "zstd", ] @@ -306,15 +172,6 @@ dependencies = [ "serde", ] -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - [[package]] name = "blake3" version = "1.5.0" @@ -338,12 +195,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - [[package]] name = "byteorder" version = "1.5.0" @@ -407,68 +258,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "clap" -version = "4.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.39", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "cli_enc" -version = "0.1.0" -dependencies = [ - "anyhow", - "bfsp", - "clap", - "fern", - "futures", - "humantime", - "log", - "reqwest", - "sqlx", - "tokio", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "colored" version = "1.9.4" @@ -492,22 +281,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - [[package]] name = "cpufeatures" version = "0.2.11" @@ -609,6 +382,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys", +] + [[package]] name = "dotenvy" version = "0.15.7" @@ -633,15 +427,6 @@ dependencies = [ "serde", ] -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -732,12 +517,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "form_urlencoded" version = "1.2.0" @@ -874,25 +653,6 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" -[[package]] -name = "h2" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "hashbrown" version = "0.14.2" @@ -960,84 +720,12 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - [[package]] name = "idna" version = "0.4.0" @@ -1067,12 +755,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - [[package]] name = "is-terminal" version = "0.4.9" @@ -1108,15 +790,6 @@ dependencies = [ "libc", ] -[[package]] -name = "js-sys" -version = "0.3.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1138,6 +811,17 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall", +] + [[package]] name = "libsodium-sys" version = "0.2.7" @@ -1196,12 +880,6 @@ dependencies = [ "sodiumoxide", ] -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "md-5" version = "0.10.6" @@ -1227,12 +905,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1354,6 +1026,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "parking_lot" version = "0.12.1" @@ -1377,17 +1055,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - [[package]] name = "paste" version = "1.0.14" @@ -1419,26 +1086,6 @@ dependencies = [ "indexmap", ] -[[package]] -name = "pin-project" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1636,6 +1283,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.10.2" @@ -1665,60 +1323,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "reqwest" -version = "0.11.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" -dependencies = [ - "base64 0.21.5", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "system-configuration", - "tokio", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", -] - -[[package]] -name = "ring" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" -dependencies = [ - "cc", - "getrandom", - "libc", - "spin 0.9.8", - "untrusted", - "windows-sys", -] - [[package]] name = "rsa" version = "0.9.3" @@ -1758,43 +1362,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "rustls" -version = "0.21.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.5", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - [[package]] name = "ryu" version = "1.0.15" @@ -1816,16 +1383,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "serde" version = "1.0.192" @@ -1858,24 +1415,11 @@ dependencies = [ ] [[package]] -name = "serde_path_to_error" -version = "0.1.14" +name = "serde_spanned" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ - "itoa", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", "serde", ] @@ -1901,15 +1445,6 @@ dependencies = [ "digest", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "signature" version = "1.6.4" @@ -1941,16 +1476,6 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.5" @@ -2214,12 +1739,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "subtle" version = "2.5.0" @@ -2248,33 +1767,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "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 = "tempfile" version = "3.8.1" @@ -2334,10 +1826,8 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys", ] @@ -2353,16 +1843,6 @@ dependencies = [ "syn 2.0.39", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -2375,46 +1855,38 @@ dependencies = [ ] [[package]] -name = "tokio-util" -version = "0.7.10" +name = "toml" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", ] [[package]] -name = "tower" -version = "0.4.13" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", - "tracing", + "serde", ] [[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" +name = "toml_edit" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] [[package]] name = "tracing" @@ -2448,12 +1920,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - [[package]] name = "typenum" version = "1.17.0" @@ -2503,12 +1969,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.4.1" @@ -2520,12 +1980,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.5.0" @@ -2557,103 +2011,12 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.39", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" - -[[package]] -name = "web-sys" -version = "0.3.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "which" version = "4.4.2" @@ -2770,13 +2133,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "winreg" -version = "0.50.0" +name = "winnow" +version = "0.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff" dependencies = [ - "cfg-if", - "windows-sys", + "memchr", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ff9ab71..f6fcf26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,25 @@ -[workspace] -resolver = "2" -members = ["bfsp", "cli", "auth", "fs"] +[package] +name = "file_server" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = { version = "1" } +tokio = { version = "1", features = [ + "net", + "fs", + "macros", + "io-util", + "rt-multi-thread", +] } +log = { version = "0.4" } +fern = { version = "0.6", features = ["colored"] } +humantime = "2" +sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] } +rand = "0.8" +bfsp = { git = "https://github.com/Billy-s-E2EE-File-Server/bfsp" } +#bfsp = { path = "../bfsp" } +async-trait = { version = "0.1" } +once_cell = "1" +futures = { version = "0.3", features = ["executor"] } +macaroon = "0.3" diff --git a/fs/Dockerfile b/Dockerfile similarity index 100% rename from fs/Dockerfile rename to Dockerfile diff --git a/auth/Cargo.toml b/auth/Cargo.toml deleted file mode 100644 index a8f16c9..0000000 --- a/auth/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "auth" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow = "1" -axum = "0.6" -rand = "0.8" -tokio = { version = "1", features = [ - "net", - "io-util", - "macros", - "rt-multi-thread", -] } -sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] } -axum-macros = "0.3" -argon2 = "0.5" -macaroon = "0.3" -fern = "0.6" -log = "0.4" -humantime = "2" -bfsp = { git = "https://github.com/billyb2/encrypted_file_server", default-features = false, features = [ - "auth", -] } -#bfsp = { path = "../bfsp", default-features = false, features = ["auth"] } diff --git a/auth/migrations/20231025032307_create_users.sql b/auth/migrations/20231025032307_create_users.sql deleted file mode 100644 index 43d38f4..0000000 --- a/auth/migrations/20231025032307_create_users.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table users ( -username text primary key not null, -password text not null, -salt text not null -) diff --git a/auth/src/main.rs b/auth/src/main.rs deleted file mode 100644 index 948037a..0000000 --- a/auth/src/main.rs +++ /dev/null @@ -1,176 +0,0 @@ -use std::env; -use std::net::SocketAddr; -use std::sync::Arc; -use std::time::{SystemTime, UNIX_EPOCH}; - -use anyhow::Result; -use argon2::password_hash::SaltString; -use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; -use axum::extract::State; -use axum::http::StatusCode; -use axum::routing::post; -use axum::{Json, Router}; -use axum_macros::debug_handler; -use bfsp::auth::{CreateUserRequest, LoginRequest, UsernameCaveat}; -use macaroon::{Macaroon, MacaroonKey}; -use rand::rngs::OsRng; -use sqlx::{Row, SqlitePool}; - -#[tokio::main] -async fn main() -> Result<()> { - fern::Dispatch::new() - .format(|out, msg, record| { - out.finish(format_args!( - "[{} {} {}] {}", - humantime::format_rfc3339(std::time::SystemTime::now()), - record.level(), - record.target(), - msg - )) - }) // Add blanket level filter - - .level(log::LevelFilter::Trace) - .level_for("sqlx", log::LevelFilter::Warn) - .level_for("hyper", log::LevelFilter::Warn) - // - and per-module overrides - // Output to stdout, files, and other Dispatch configurations - .chain(std::io::stdout()) - .chain(fern::log_file("output.log").unwrap()) - // Apply globally - .apply() - .unwrap(); - - macaroon::initialize().unwrap(); - //FIXME: please don't hard code the authentication key - let key = Arc::new(MacaroonKey::generate(b"key")); - - let pool = Arc::new( - sqlx::SqlitePool::connect( - &env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite:./data.db".to_string()), - ) - .await?, - ); - - // build our application with a route - let app = Router::new() - // `GET /` goes to `root` - .route("/create_user", post(create_user)) - .route("/login_user", post(login)) - .with_state(pool) - .with_state(key); - - // run our app with hyper - // `axum::Server` is a re-export of `hyper::Server` - let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); - - axum::Server::bind(&addr) - .serve(app.into_make_service()) - .await - .unwrap(); - - Ok(()) -} - -async fn create_user( - State(pool): State>, - Json(req): Json, -) -> (StatusCode, String) { - let argon2 = Argon2::default(); - let salt: SaltString = SaltString::generate(&mut OsRng); - let hashed_password = match argon2.hash_password(req.password.as_bytes(), &salt) { - Ok(password) => password, - Err(err) => { - //TODO: log errors - return ( - StatusCode::INTERNAL_SERVER_ERROR, - "Internal server error".to_string(), - ); - } - }; - - match sqlx::query("insert into users ( email, password, salt ) values ( ?, ?, ?, ? )") - .bind(req.email) - .bind(hashed_password.to_string()) - .bind(salt.to_string()) - .execute(pool.as_ref()) - .await - { - Ok(_) => (StatusCode::OK, "registered user".to_string()), - Err(err) => match err.into_database_error().unwrap().kind() { - sqlx::error::ErrorKind::UniqueViolation => todo!(), - sqlx::error::ErrorKind::ForeignKeyViolation => todo!(), - sqlx::error::ErrorKind::NotNullViolation => todo!(), - sqlx::error::ErrorKind::CheckViolation => todo!(), - sqlx::error::ErrorKind::Other => todo!(), - _ => todo!(), - }, - } -} - -async fn login( - State(pool): State>, - Json(login_request): Json, -) -> (StatusCode, String) { - println!("Received login reqest"); - - let password: Option = sqlx::query("select password from users where username = ?") - .bind(&login_request.email) - .fetch_optional(pool.as_ref()) - .await - .unwrap() - .map(|row| row.get::("password")); - - let password_hash = match password { - Some(password) => password, - None => { - return ( - StatusCode::UNAUTHORIZED, - "Username or password is incorrect".to_string(), - ); - } - }; - - let password_hash = PasswordHash::new(&password_hash).unwrap(); - if Argon2::default() - .verify_password(login_request.password.as_bytes(), &password_hash) - .is_err() - { - return ( - StatusCode::UNAUTHORIZED, - "Username or password is incorrect".to_string(), - ); - } - - let key = MacaroonKey::generate(b"key"); - - let mut macaroon = match Macaroon::create( - None, - &key, - format!("{}-{}", login_request.email, rand::random::()).into(), - ) { - Ok(macaroon) => macaroon, - //FIXME: deal with this - Err(error) => panic!("Error creating macaroon: {:?}", error), - }; - - macaroon.add_first_party_caveat( - UsernameCaveat { - username: login_request.email, - } - .into(), - ); - macaroon.add_first_party_caveat( - format!( - "expires = {}", - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() - ) - .into(), - ); - - ( - StatusCode::OK, - macaroon.serialize(macaroon::Format::V2JSON).unwrap(), - ) -} diff --git a/bfsp/Cargo.toml b/bfsp/Cargo.toml deleted file mode 100644 index fd174a7..0000000 --- a/bfsp/Cargo.toml +++ /dev/null @@ -1,39 +0,0 @@ -[package] -name = "bfsp" -version = "0.1.0" -edition = "2021" -build = "build.rs" - -[dependencies] -blake3 = { version = "1", features = ["rayon"] } -anyhow = { version = "1" } -tokio = { version = "1", features = ["fs", "io-util"] } -sqlx = { version = "0.7", default-features = false, features = ["sqlite"] } -uuid = { version = "1", features = ["v4"] } -chacha20poly1305 = { version = "0.10", features = ["std"], optional = true } -zstd = "0.13" - -serde = { version = "1", optional = true } -serde_derive = { version = "1", optional = true } -regex = { version = "1", optional = true } -macaroon = { version = "0.3", optional = true } -prost = "0.12" -bytes = "1" - -[build-dependencies] -prost-build = { version = "0.12" } - -[dev-dependencies] -tokio = { version = "1", features = [ - "fs", - "io-util", - "macros", - "rt-multi-thread", -] } -sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio"] } - -[features] -default = ["auth", "file", "cli"] -file = ["chacha20poly1305", "macaroon"] -auth = ["macaroon", "serde", "serde_derive", "regex"] -cli = ["file"] diff --git a/bfsp/build.rs b/bfsp/build.rs deleted file mode 100644 index 196d64a..0000000 --- a/bfsp/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::io::Result; -fn main() -> Result<()> { - prost_build::compile_protos(&["src/bfsp.proto"], &["src/"])?; - Ok(()) -} diff --git a/bfsp/rustfmt.toml b/bfsp/rustfmt.toml deleted file mode 100644 index 3a26366..0000000 --- a/bfsp/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -edition = "2021" diff --git a/bfsp/src/auth.rs b/bfsp/src/auth.rs deleted file mode 100644 index 0bc4310..0000000 --- a/bfsp/src/auth.rs +++ /dev/null @@ -1,108 +0,0 @@ -pub use crate::bfsp::files::file_server_message::Authentication; -use anyhow::{anyhow, Result}; -use macaroon::ByteString; -use prost::Message; -use regex::Regex; - -#[derive(Clone)] -pub struct UsernameCaveat { - pub username: String, -} - -impl Into for UsernameCaveat { - fn into(self) -> ByteString { - self.to_string().into() - } -} - -impl ToString for UsernameCaveat { - fn to_string(&self) -> String { - format!("username = {}", self.username) - } -} - -impl TryFrom for UsernameCaveat { - type Error = anyhow::Error; - - fn try_from(value: ByteString) -> Result { - let value: String = String::from_utf8(value.0.clone())?; - - let re = Regex::new("username = (?[a-zA-Z0-9_-]*)")?; - let Some(caps) = re.captures(&value) else { - return Err(anyhow!("invalid username caveat")); - }; - let username = &caps["username"]; - - Ok(Self { - username: username.to_string(), - }) - } -} - -#[derive(Clone)] -pub struct ExpirationCaveat { - pub expiration: u64, -} - -impl Into for ExpirationCaveat { - fn into(self) -> ByteString { - self.to_string().into() - } -} - -impl ToString for ExpirationCaveat { - fn to_string(&self) -> String { - format!("expires = {}", self.expiration) - } -} - -impl TryFrom<&ByteString> for ExpirationCaveat { - type Error = anyhow::Error; - - fn try_from(value: &ByteString) -> Result { - let value: String = String::from_utf8(value.0.clone())?; - - let re = Regex::new("expires = (?[a-zA-Z0-9_-]*)")?; - let Some(caps) = re.captures(&value) else { - return Err(anyhow!("invalid expiration caveat")); - }; - let expiration = &caps["expires"].to_string(); - let expiration: u64 = expiration.parse()?; - - Ok(Self { expiration }) - } -} - -impl Authentication { - pub fn to_bytes(&self) -> Vec { - let mut buf = self.encode_to_vec(); - let mut msg = (buf.len() as u32).to_le_bytes().to_vec(); - msg.append(&mut buf); - - msg - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - Self::decode(bytes).map_err(|e| anyhow!("{e:?}")) - } -} - -#[derive(serde_derive::Serialize, serde_derive::Deserialize)] -pub struct CreateUserRequest { - pub email: String, - pub password: String, -} - -impl CreateUserRequest { - /// Returns true if the email is valid, false otherwise - pub fn validate_email() -> bool { - //FIXME - true - } -} - -#[derive(serde_derive::Serialize, serde_derive::Deserialize)] -pub struct LoginRequest { - pub email: String, - pub password: String, -} diff --git a/bfsp/src/bfsp.proto b/bfsp/src/bfsp.proto deleted file mode 100644 index c8b9647..0000000 --- a/bfsp/src/bfsp.proto +++ /dev/null @@ -1,71 +0,0 @@ -syntax = "proto3"; - -package bfsp.files; - -message FileServerMessage { - message UploadChunkQuery { - ChunkMetadata chunk_metadata = 1; - bytes chunk = 2; - } - - message ChunksUploadedQuery { - repeated bytes chunk_ids = 1; - } - - message DownloadChunkQuery { - bytes chunk_id = 1; - } - - - message Authentication { - string macaroon = 1; - } - - Authentication auth = 1; - - oneof message { - UploadChunkQuery upload_chunk_query = 2; - ChunksUploadedQuery chunks_uploaded_query = 3; - DownloadChunkQuery download_chunk_query = 4; - } -} - -message UploadChunkResp { - optional string err = 2; -} - -message DownloadChunkResp { - message ChunkData { - ChunkMetadata chunk_metadata = 1; - bytes chunk = 2; - } - - oneof response { - ChunkData chunk_data = 1; - string err = 2; - } -} - -message ChunksUploadedQueryResp { - message ChunkUploaded { - bytes chunk_id = 1; - bool uploaded = 2; - } - - message ChunksUploaded { - repeated ChunkUploaded chunks = 1; - } - - oneof response { - ChunksUploaded chunks = 1; - string err = 2; - } -} - -message ChunkMetadata { - bytes id = 1; - bytes hash = 2; - uint32 size = 3; - uint64 indice = 4; - bytes nonce = 5; -} diff --git a/bfsp/src/cli.rs b/bfsp/src/cli.rs deleted file mode 100644 index e8945e2..0000000 --- a/bfsp/src/cli.rs +++ /dev/null @@ -1,168 +0,0 @@ -use anyhow::{anyhow, Result}; -use blake3::Hasher; -use std::{collections::HashMap, io::SeekFrom}; -use tokio::{ - fs::File, - io::{AsyncReadExt, AsyncSeekExt}, -}; - -pub use crate::bfsp::files::ChunkMetadata; -use crate::{ChunkHash, ChunkID, EncryptionKey, EncryptionNonce, FileHash}; - -#[derive(Clone, Debug, PartialEq)] -pub struct FileHeader { - pub hash: FileHash, - pub chunk_size: u32, - pub chunks: HashMap, - pub chunk_indices: HashMap, -} - -impl FileHeader { - pub fn total_file_size(&self) -> u64 { - self.chunks.values().map(|chunk| chunk.size as u64).sum() - } -} - -impl FileHeader { - /// Random file ID - pub async fn from_file(file: &mut File) -> Result { - file.rewind().await?; - - let metadata = file.metadata().await?; - let size = metadata.len(); - let chunk_size = match size { - // 8KiB for anything less than 256 KiB - 0..=262_144 => 8192, - // 64KiB for anything up to 8MiB - 262_145..=8388608 => 65536, - // 8MiB for anything higher - _ => 8388608, - }; - - let mut total_file_hasher = Hasher::new(); - // Use parallel hashing for data larger than 256KiB - let use_parallel_chunk = use_parallel_hasher(chunk_size); - - let mut chunk_buf = vec![0; chunk_size]; - let mut chunk_buf_index = 0; - - let mut chunks = HashMap::new(); - let mut chunk_indices = HashMap::new(); - let mut chunk_index = 0; - - loop { - // First, read into the buffer until it's full, or we hit an EOF - let eof = loop { - if chunk_buf_index == chunk_buf.len() { - break false; - } - match file.read(&mut chunk_buf[chunk_buf_index..]).await { - Ok(num_bytes_read) => match num_bytes_read { - 0 => break true, - b => chunk_buf_index += b, - }, - Err(err) => match err.kind() { - std::io::ErrorKind::UnexpectedEof => break true, - _ => return anyhow::Result::Err(err.into()), - }, - }; - }; - - let chunk_buf = &chunk_buf[..chunk_buf_index]; - - let mut chunk_hasher = Hasher::new(); - // Next, take the hash of the chunk that was read - match use_parallel_chunk { - true => { - total_file_hasher.update_rayon(chunk_buf); - chunk_hasher.update_rayon(chunk_buf); - } - false => { - total_file_hasher.update(chunk_buf); - chunk_hasher.update(chunk_buf); - } - }; - - let chunk_hash: ChunkHash = chunk_hasher.finalize().into(); - let chunk_id = ChunkID::new(&chunk_hash).to_bytes().to_vec(); - let nonce = EncryptionNonce::new(&chunk_hash); - - // Finally, insert some chunk metadata - chunks.insert( - chunk_id.clone(), - ChunkMetadata { - id: chunk_id.clone(), - indice: chunk_index, - hash: chunk_hash.to_bytes().to_vec(), - size: chunk_buf.len() as u32, - nonce: nonce.to_bytes().to_vec(), - }, - ); - chunk_indices.insert(chunk_id, chunk_index); - - chunk_index += 1; - - if eof { - break; - } - chunk_buf_index = 0; - } - - file.rewind().await?; - - Ok(Self { - hash: total_file_hasher.finalize().into(), - chunk_size: chunk_size as u32, - chunks: chunks - .into_iter() - .map(|(id, meta)| (ChunkID::try_from(id).unwrap(), meta)) - .collect(), - chunk_indices: chunk_indices - .into_iter() - .map(|(id, index)| (ChunkID::try_from(id).unwrap(), index)) - .collect(), - }) - } -} - -//TODO: can this be a slice? -pub async fn compressed_encrypted_chunk_from_file( - file_header: &FileHeader, - file: &mut File, - chunk_id: ChunkID, - key: &EncryptionKey, -) -> Result> { - let chunk_meta = file_header - .chunks - .get(&chunk_id) - .ok_or_else(|| anyhow!("Chunk not found"))?; - - let chunk_indice = *file_header - .chunk_indices - .get(&chunk_id) - .ok_or_else(|| anyhow!("Chunk not found"))?; - - let byte_index = chunk_indice as u64 * file_header.chunk_size as u64; - - file.seek(SeekFrom::Start(byte_index)).await?; - - let mut buf = Vec::with_capacity(chunk_meta.size as usize); - file.take(chunk_meta.size as u64) - .read_to_end(&mut buf) - .await?; - - println!("Size before compression: {}KB", buf.len()); - - let mut buf = zstd::bulk::compress(&buf, 15)?; - println!("Size after compression: {}KB", buf.len()); - - file.rewind().await?; - - key.encrypt_chunk_in_place(&mut buf, &chunk_meta)?; - - Ok(buf) -} - -pub const fn use_parallel_hasher(size: usize) -> bool { - size > 262_144 -} diff --git a/bfsp/src/crypto.rs b/bfsp/src/crypto.rs deleted file mode 100644 index daa1424..0000000 --- a/bfsp/src/crypto.rs +++ /dev/null @@ -1,175 +0,0 @@ -use anyhow::{anyhow, Result}; -use blake3::Hasher; -use chacha20poly1305::{aead::OsRng, AeadInPlace, Key, KeyInit, XChaCha20Poly1305}; -use sqlx::Sqlite; -use tokio::{fs::File, io::AsyncReadExt}; - -use crate::{ChunkHash, ChunkMetadata, FileHash}; - -pub struct EncryptionKey { - key: Key, -} - -impl TryFrom> for EncryptionKey { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> Result { - let mut key: Key = [0; 32].into(); - key.copy_from_slice(&value); - - Ok(Self { key }) - } -} - -impl sqlx::Type for EncryptionKey { - fn type_info() -> ::TypeInfo { - <&[u8] as sqlx::Type>::type_info() - } -} - -impl sqlx::Encode<'_, Sqlite> for EncryptionKey { - fn encode_by_ref( - &self, - buf: &mut >::ArgumentBuffer, - ) -> sqlx::encode::IsNull { - let nonce = self.key.to_vec().into(); - buf.push(sqlx::sqlite::SqliteArgumentValue::Blob(nonce)); - - sqlx::encode::IsNull::No - } -} - -impl EncryptionKey { - pub fn new() -> Self { - let key = XChaCha20Poly1305::generate_key(&mut OsRng); - Self { key } - } - - pub fn encrypt_chunk_in_place( - &self, - chunk: &mut Vec, - chunk_meta: &ChunkMetadata, - ) -> Result<()> { - let key = XChaCha20Poly1305::new(&self.key); - key.encrypt_in_place( - chunk_meta.nonce.as_slice().into(), - chunk_meta.id.as_slice(), - chunk, - )?; - - Ok(()) - } - pub fn decrypt_chunk_in_place( - &self, - chunk: &mut Vec, - chunk_meta: &ChunkMetadata, - ) -> Result<()> { - let key = XChaCha20Poly1305::new(&self.key); - key.decrypt_in_place( - chunk_meta.nonce.as_slice().into(), - chunk_meta.id.as_slice(), - chunk, - )?; - *chunk = zstd::bulk::decompress(&chunk, chunk_meta.size as usize)?; - Ok(()) - } -} - -#[derive(Clone, sqlx::FromRow, Debug, PartialEq)] -pub struct EncryptionNonce { - nonce: [u8; 24], -} - -impl EncryptionNonce { - pub fn to_bytes(&self) -> [u8; 24] { - self.nonce - } -} - -impl sqlx::Type for EncryptionNonce { - fn type_info() -> ::TypeInfo { - <&[u8] as sqlx::Type>::type_info() - } -} - -impl sqlx::Encode<'_, Sqlite> for EncryptionNonce { - fn encode_by_ref( - &self, - buf: &mut >::ArgumentBuffer, - ) -> sqlx::encode::IsNull { - let nonce = self.nonce.to_vec().into(); - buf.push(sqlx::sqlite::SqliteArgumentValue::Blob(nonce)); - - sqlx::encode::IsNull::No - } -} - -impl TryFrom> for EncryptionNonce { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> Result { - Ok(Self { - nonce: value.try_into().map_err(|e| anyhow!("{e:?}"))?, - }) - } -} - -impl EncryptionNonce { - pub fn new(chunk_hash: &ChunkHash) -> Self { - let mut nonce: [u8; 24] = [0; 24]; - nonce.copy_from_slice(&chunk_hash.to_bytes()[0..24]); - - Self { nonce } - } -} - -pub async fn hash_file(file: &mut File) -> Result { - let chunk_size = 8388608 * 8; - - let mut total_file_hasher = Hasher::new(); - let mut chunk_buf = vec![0; chunk_size]; - let mut chunk_buf_index = 0; - - loop { - // First, read into the buffer until it's full, or we hit an EOF - let eof = loop { - if chunk_buf_index == chunk_buf.len() { - break false; - } - match file.read(&mut chunk_buf[chunk_buf_index..]).await { - Ok(num_bytes_read) => match num_bytes_read { - 0 => break true, - b => chunk_buf_index += b, - }, - Err(err) => match err.kind() { - std::io::ErrorKind::UnexpectedEof => break true, - _ => return anyhow::Result::Err(err.into()), - }, - }; - }; - - let chunk_buf = &chunk_buf[..chunk_buf_index]; - - total_file_hasher.update_rayon(chunk_buf); - - if eof { - break; - } - - chunk_buf_index = 0; - } - - Ok(FileHash(total_file_hasher.finalize())) -} - -pub fn hash_chunk(chunk: &[u8]) -> ChunkHash { - let mut hasher = Hasher::new(); - hasher.update(chunk); - hasher.finalize().into() -} - -pub fn parallel_hash_chunk(chunk: &[u8]) -> ChunkHash { - let mut hasher = Hasher::new(); - hasher.update(chunk); - hasher.finalize().into() -} diff --git a/bfsp/src/file.rs b/bfsp/src/file.rs deleted file mode 100644 index c129969..0000000 --- a/bfsp/src/file.rs +++ /dev/null @@ -1,308 +0,0 @@ -pub use crate::crypto::*; - -pub use crate::bfsp::files::*; -use anyhow::{anyhow, Error, Result}; -pub use prost::Message; -use sqlx::{sqlite::SqliteRow, Row, Sqlite}; -use std::{ - fmt::{Debug, Display}, - str::FromStr, -}; -use uuid::Uuid; - -impl FileServerMessage { - pub fn to_bytes(&self) -> Vec { - self.encode_to_vec().prepend_len() - } - pub fn from_bytes(bytes: &[u8]) -> Result { - Self::decode(bytes).map_err(|e| anyhow!("{e:?}")) - } -} - -#[derive(Copy, Clone, Eq, Hash, PartialEq)] -pub struct ChunkID { - pub id: u128, -} - -impl Debug for ChunkID { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&format!("{:#x}", self.id)) - } -} - -impl ChunkID { - pub fn to_bytes(&self) -> [u8; 16] { - self.id.to_le_bytes() - } - pub fn from_bytes(buf: [u8; 16]) -> Self { - Self { - id: u128::from_le_bytes(buf), - } - } -} - -impl sqlx::Type for ChunkID { - fn type_info() -> ::TypeInfo { - >::type_info() - } -} - -impl std::fmt::Display for ChunkID { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let uuid = Uuid::from_u128(self.id); - f.write_str(&uuid.to_string()) - } -} - -impl sqlx::FromRow<'_, SqliteRow> for ChunkID { - fn from_row(row: &SqliteRow) -> std::result::Result { - row.try_get::("id") - .map(|chunk_id: String| Self { - id: Uuid::from_str(&chunk_id).unwrap().as_u128(), - }) - } -} - -impl sqlx::Encode<'_, Sqlite> for ChunkID { - fn encode_by_ref( - &self, - buf: &mut >::ArgumentBuffer, - ) -> sqlx::encode::IsNull { - buf.push(sqlx::sqlite::SqliteArgumentValue::Text( - Uuid::from_u128(self.id).to_string().into(), - )); - - sqlx::encode::IsNull::No - } -} - -impl TryFrom> for ChunkID { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> Result { - let uuid_bytes: [u8; 16] = value.try_into().map_err(|e| anyhow!("{e:?}"))?; - let uuid = Uuid::from_bytes(uuid_bytes); - - Ok(ChunkID { id: uuid.as_u128() }) - } -} - -impl TryFrom for ChunkID { - type Error = Error; - - fn try_from(value: String) -> std::result::Result { - Ok(ChunkID { - id: Uuid::from_str(&value)?.as_u128(), - }) - } -} - -impl ChunkID { - /// Uses the chunk has as an RNG, FIXME insecure as shit - /// This reduces the number of unknown bits in the file hash by HALF, which reduces the anonimity of any files being uploaded - pub fn new(hash: &ChunkHash) -> Self { - let bytes: [u8; blake3::OUT_LEN] = *hash.0.as_bytes(); - let uuid_bytes: [u8; 16] = bytes[..16].try_into().unwrap(); - let uuid = Uuid::from_bytes(uuid_bytes); - - Self { id: uuid.as_u128() } - } -} - -// TODO: encrypt chunk metadata that isn't ID?? -impl ChunkMetadata { - pub fn to_bytes(&self) -> Vec { - let mut buf = self.encode_to_vec(); - let mut msg = (buf.len() as u32).to_le_bytes().to_vec(); - msg.append(&mut buf); - msg - } - pub fn from_bytes(buf: &[u8]) -> Result { - Self::decode(buf).map_err(|e| anyhow!("{e:?}")) - } -} - -#[derive(PartialEq)] -pub struct ChunkHash(blake3::Hash); - -impl ChunkHash { - pub fn to_bytes(&self) -> &[u8] { - self.0.as_bytes() - } - pub fn from_bytes(buf: [u8; blake3::OUT_LEN]) -> Self { - Self(blake3::Hash::from_bytes(buf)) - } -} - -impl From for ChunkHash { - fn from(value: blake3::Hash) -> Self { - Self(value) - } -} - -impl sqlx::Type for ChunkHash { - fn type_info() -> ::TypeInfo { - >::type_info() - } -} - -impl sqlx::FromRow<'_, SqliteRow> for ChunkHash { - fn from_row(row: &SqliteRow) -> std::result::Result { - row.try_get::("hash") - .map(|hash: String| Self(blake3::Hash::from_str(&hash).unwrap())) - } -} - -impl sqlx::Encode<'_, Sqlite> for ChunkHash { - fn encode_by_ref( - &self, - buf: &mut >::ArgumentBuffer, - ) -> sqlx::encode::IsNull { - buf.push(sqlx::sqlite::SqliteArgumentValue::Text( - self.to_string().into(), - )); - sqlx::encode::IsNull::No - } -} - -impl ToString for ChunkHash { - fn to_string(&self) -> String { - self.0.to_string() - } -} - -impl TryFrom<&[u8]> for ChunkHash { - type Error = anyhow::Error; - - fn try_from(value: &[u8]) -> anyhow::Result { - let slice: &[u8; blake3::OUT_LEN] = value.try_into()?; - Ok(Self(blake3::Hash::from_bytes(*slice))) - } -} - -impl TryFrom> for ChunkHash { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> anyhow::Result { - value.as_slice().try_into() - } -} - -impl Into<[u8; blake3::OUT_LEN]> for ChunkHash { - fn into(self) -> [u8; blake3::OUT_LEN] { - *self.0.as_bytes() - } -} - -impl TryFrom for ChunkHash { - type Error = anyhow::Error; - - fn try_from(value: String) -> std::result::Result { - Ok(Self(blake3::Hash::from_str(&value)?)) - } -} - -#[derive(Clone, Debug, PartialEq)] -pub struct FileHash(pub(crate) blake3::Hash); - -impl std::fmt::Display for FileHash { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.0.to_string()) - } -} - -impl sqlx::FromRow<'_, SqliteRow> for FileHash { - fn from_row(row: &SqliteRow) -> std::result::Result { - row.try_get::("file_hash") - .map(|hash: String| Self(blake3::Hash::from_str(&hash).unwrap())) - } -} - -impl sqlx::Type for FileHash { - fn type_info() -> ::TypeInfo { - >::type_info() - } -} - -impl sqlx::Encode<'_, Sqlite> for FileHash { - fn encode_by_ref( - &self, - buf: &mut >::ArgumentBuffer, - ) -> sqlx::encode::IsNull { - buf.push(sqlx::sqlite::SqliteArgumentValue::Text( - self.0.to_string().into(), - )); - - sqlx::encode::IsNull::No - } -} - -impl From for FileHash { - fn from(value: blake3::Hash) -> Self { - Self(value) - } -} - -impl TryFrom for FileHash { - type Error = anyhow::Error; - - fn try_from(value: String) -> Result { - Ok(Self(blake3::Hash::from_str(&value)?)) - } -} - -impl TryFrom<&[u8]> for FileHash { - type Error = anyhow::Error; - - fn try_from(value: &[u8]) -> anyhow::Result { - let slice: &[u8; blake3::OUT_LEN] = value.try_into().map_err(|_err| { - anyhow!( - "Could not convert slice of length {} to [u8; 32]", - value.len() - ) - })?; - Ok(Self(blake3::Hash::from_bytes(*slice))) - } -} - -impl TryFrom> for FileHash { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> anyhow::Result { - value.as_slice().try_into() - } -} - -#[derive(Debug)] -pub struct AuthErr; - -impl Display for AuthErr { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Authenticaiton error") - } -} - -impl std::error::Error for AuthErr {} - -#[derive(Debug)] -pub struct ChunkNotFound; - -impl Display for ChunkNotFound { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Chunk not found") - } -} - -impl std::error::Error for ChunkNotFound {} - -pub trait PrependLen { - fn prepend_len(self) -> Self; -} -impl PrependLen for Vec { - fn prepend_len(mut self) -> Self { - let len = self.len(); - let mut len_bytes = (len as u32).to_le_bytes().to_vec(); - len_bytes.append(&mut self); - len_bytes - } -} diff --git a/bfsp/src/lib.rs b/bfsp/src/lib.rs deleted file mode 100644 index ed340b1..0000000 --- a/bfsp/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -/// Billy's file sync protocol -#[cfg(test)] -mod test; - -pub(crate) mod bfsp { - pub(crate) mod files { - include!(concat!(env!("OUT_DIR"), "/bfsp.files.rs")); - } -} - -#[cfg(feature = "cli")] -pub mod cli; - -#[cfg(feature = "file")] -pub mod crypto; -#[cfg(feature = "file")] -pub mod file; -#[cfg(feature = "file")] -pub use file::*; - -#[cfg(feature = "auth")] -pub mod auth; diff --git a/bfsp/src/test.rs b/bfsp/src/test.rs deleted file mode 100644 index 2018b0e..0000000 --- a/bfsp/src/test.rs +++ /dev/null @@ -1,98 +0,0 @@ -use anyhow::Result; -use tokio::fs; - -use crate::cli::FileHeader; - -//FIXME -/* -#[tokio::test] -async fn file_header_medium_file() -> Result<()> { - let mut tux_file = fs::File::open("./test_files/tux_huge.png").await?; - let file_header = FileHeader::from_file(&mut tux_file, None).await?; - - let chunks: HashMap = [ - ( - 0, - ChunkMetadata { - id: 0, - hash: "b2262595c40fcc22b7056107b4f744e01cca095f0cc4b0965d261396a370720a" - .to_string(), - size: 65536 - } - ), - ( - 5, - ChunkMetadata { - id: 5, - hash: "1828f9fcd28d182d27af0383532c110db97a180a7b5b731aa814cc21bbf21513" - .to_string(), - size: 65536 - } - ), - ( - 1, - ChunkMetadata { - id: 1, - hash: "4a0bf35c7cd77c033caf0d4f5be37e888d40a4143a4cd21ae3d7e640646b06dc" - .to_string(), - size: 65536 - } - ), - ( - 6, - ChunkMetadata { - id: 6, - hash: "1fcc2640c103261fac764166ad9f6a38387d48b539883071beee69d8b032c762" - .to_string(), - size: 2964 - } - ), - ( - 2, - ChunkMetadata { - id: 2, - hash: "60c225e18cfd5b83a08e61896d2f6f8a760de1645a82118c3cc71012b7a857f7" - .to_string(), - size: 65536 - } - ), - ( - 3, - ChunkMetadata { - id: 3, - hash: "143e04b49e151902492b93f2aa25a5306ba17e2ef5da129e072aae16aabf99d2" - .to_string(), - size: 65536 - } - ), - ( - 4, - ChunkMetadata { - id: 4, - hash: "f6897e05c8a3929bbf2b64a2003c43dd26c65cd2d639f8d9938145dc5c06efcc" - .to_string(), - size: 65536 - } - ) - ].into(); - - let chunk_size = 65536; - - assert_eq!(file_header.chunk_size, chunk_size); - assert_eq!(file_header.chunks, chunks); - - - Ok(()) -} -*/ - -#[tokio::test] -async fn test_consistent_file_headers() -> Result<()> { - let mut tux_file = fs::File::open("./test_files/tux_huge.png").await?; - let file_header = FileHeader::from_file(&mut tux_file).await?; - let file_header2 = FileHeader::from_file(&mut tux_file).await?; - - assert_eq!(file_header, file_header2); - - Ok(()) -} diff --git a/bfsp/test_files/tux_huge.png b/bfsp/test_files/tux_huge.png deleted file mode 100644 index f7a1bd8..0000000 --- a/bfsp/test_files/tux_huge.png +++ /dev/null @@ -1,234 +0,0 @@ -"The Lottery" (1948) -by Shirley Jackson -The morning of June 27th was clear and sunny, with the fresh warmth of a full-summer day; the flowers -were blossoming profusely and the grass was richly green. The people of the village began to gather in -the square, between the post office and the bank, around ten o'clock; in some towns there were so many -people that the lottery took two days and had to be started on June 2th. but in this village, where there -were only about three hundred people, the whole lottery took less than two hours, so it could begin at ten -o'clock in the morning and still be through in time to allow the villagers to get home for noon dinner. -The children assembled first, of course. School was recently over for the summer, and the feeling of -liberty sat uneasily on most of them; they tended to gather together quietly for a while before they broke -into boisterous play. and their talk was still of the classroom and the teacher, of books and reprimands. -Bobby Martin had already stuffed his pockets full of stones, and the other boys soon followed his -example, selecting the smoothest and roundest stones; Bobby and Harry Jones and Dickie Delacroix-- the -villagers pronounced this name "Dellacroy"--eventually made a great pile of stones in one corner of the -square and guarded it against the raids of the other boys. The girls stood aside, talking among themselves, -looking over their shoulders at rolled in the dust or clung to the hands of their older brothers or sisters. -Soon the men began to gather. surveying their own children, speaking of planting and rain, tractors and -taxes. They stood together, away from the pile of stones in the corner, and their jokes were quiet and they -smiled rather than laughed. The women, wearing faded house dresses and sweaters, came shortly after -their menfolk. They greeted one another and exchanged bits of gossip as they went to join their husbands. -Soon the women, standing by their husbands, began to call to their children, and the children came -reluctantly, having to be called four or five times. Bobby Martin ducked under his mother's grasping hand -and ran, laughing, back to the pile of stones. His father spoke up sharply, and Bobby came quickly and -took his place between his father and his oldest brother. -The lottery was conducted--as were the square dances, the teen club, the Halloween program--by Mr. -Summers. who had time and energy to devote to civic activities. He was a round-faced, jovial man and he -ran the coal business, and people were sorry for him. because he had no children and his wife was a -scold. When he arrived in the square, carrying the black wooden box, there was a murmur of -conversation among the villagers, and he waved and called. "Little late today, folks." The postmaster, Mr. -Graves, followed him, carrying a three- legged stool, and the stool was put in the center of the square and -Mr. Summers set the black box down on it. The villagers kept their distance, leaving a space between -themselves and the stool. and when Mr. Summers said, "Some of you fellows want to give me a hand?" -there was a hesitation before two men. Mr. Martin and his oldest son, Baxter. came forward to hold the -box steady on the stool while Mr. Summers stirred up the papers inside it. -The original paraphernalia for the lottery had been lost long ago, and the black box now resting on the -stool had been put into use even before Old Man Warner, the oldest man in town, was born. Mr. -Summers spoke frequently to the villagers about making a new box, but no one liked to upset even as -much tradition as was represented by the black box. There was a story that the present box had been -made with some pieces of the box that had preceded it, the one that had been constructed when the first -people settled down to make a village here. Every year, after the lottery, Mr. Summers began talking -again about a new box, but every year the subject was allowed to fade off without anything's being done. -file:///Users/carolynsigler/Desktop/lotry.html (1 of 8)1/23/2005 7:58:04 AM -The Lottery--Shirley Jackson -The black box grew shabbier each year: by now it was no longer completely black but splintered badly -along one side to show the original wood color, and in some places faded or stained. -Mr. Martin and his oldest son, Baxter, held the black box securely on the stool until Mr. Summers had -stirred the papers thoroughly with his hand. Because so much of the ritual had been forgotten or -discarded, Mr. Summers had been successful in having slips of paper substituted for the chips of wood -that had been used for generations. Chips of wood, Mr. Summers had argued. had been all very well -when the village was tiny, but now that the population was more than three hundred and likely to keep on -growing, it was necessary to use something that would fit more easily into he black box. The night before -the lottery, Mr. Summers and Mr. Graves made up the slips of paper and put them in the box, and it was -then taken to the safe of Mr. Summers' coal company and locked up until Mr. Summers was ready to take -it to the square next morning. The rest of the year, the box was put way, sometimes one place, sometimes -another; it had spent one year in Mr. Graves's barn and another year underfoot in the post office. and -sometimes it was set on a shelf in the Martin grocery and left there. -There was a great deal of fussing to be done before Mr. Summers declared the lottery open. There were -the lists to make up--of heads of families. heads of households in each family. members of each -household in each family. There was the proper swearing-in of Mr. Summers by the postmaster, as the -official of the lottery; at one time, some people remembered, there had been a recital of some sort, -performed by the official of the lottery, a perfunctory. tuneless chant that had been rattled off duly each -year; some people believed that the official of the lottery used to stand just so when he said or sang it, -others believed that he was supposed to walk among the people, but years and years ago this p3rt of the -ritual had been allowed to lapse. There had been, also, a ritual salute, which the official of the lottery had -had to use in addressing each person who came up to draw from the box, but this also had changed with -time, until now it was felt necessary only for the official to speak to each person approaching. Mr. -Summers was very good at all this; in his clean white shirt and blue jeans. with one hand resting -carelessly on the black box. he seemed very proper and important as he talked interminably to Mr. Graves -and the Martins. -Just as Mr. Summers finally left off talking and turned to the assembled villagers, Mrs. Hutchinson came -hurriedly along the path to the square, her sweater thrown over her shoulders, and slid into place in the -back of the crowd. "Clean forgot what day it was," she said to Mrs. Delacroix, who stood next to her, and -they both laughed softly. "Thought my old man was out back stacking wood," Mrs. Hutchinson went on. -"and then I looked out the window and the kids was gone, and then I remembered it was the twentyseventh and came a-running." She dried her hands on her apron, and Mrs. Delacroix said, "You're in time, -though. They're still talking away up there." -Mrs. Hutchinson craned her neck to see through the crowd and found her husband and children standing -near the front. She tapped Mrs. Delacroix on the arm as a farewell and began to make her way through -the crowd. The people separated good-humoredly to let her through: two or three people said. in voices -just loud enough to be heard across the crowd, "Here comes your, Missus, Hutchinson," and "Bill, she -made it after all." Mrs. Hutchinson reached her husband, and Mr. Summers, who had been waiting, said -cheerfully. "Thought we were going to have to get on without you, Tessie." Mrs. Hutchinson said. -grinning, "Wouldn't have me leave m'dishes in the sink, now, would you. Joe?," and soft laughter ran -through the crowd as the people stirred back into position after Mrs. Hutchinson's arrival. -"Well, now." Mr. Summers said soberly, "guess we better get started, get this over with, so's we can go -back to work. Anybody ain't here?" -file:///Users/carolynsigler/Desktop/lotry.html (2 of 8)1/23/2005 7:58:04 AM -The Lottery--Shirley Jackson -"Dunbar." several people said. "Dunbar. Dunbar." -Mr. Summers consulted his list. "Clyde Dunbar." he said. "That's right. He's broke his leg, hasn't he? -Who's drawing for him?" -"Me. I guess," a woman said. and Mr. Summers turned to look at her. "Wife draws for her husband." Mr. -Summers said. "Don't you have a grown boy to do it for you, Janey?" Although Mr. Summers and -everyone else in the village knew the answer perfectly well, it was the business of the official of the -lottery to ask such questions formally. Mr. Summers waited with an expression of polite interest while -Mrs. Dunbar answered. -"Horace's not but sixteen vet." Mrs. Dunbar said regretfully. "Guess I gotta fill in for the old man this -year." -"Right." Sr. Summers said. He made a note on the list he was holding. Then he asked, "Watson boy -drawing this year?" -A tall boy in the crowd raised his hand. "Here," he said. "I'm drawing for my mother and me." He blinked -his eyes nervously and ducked his head as several voices in the crowd said thin#s like "Good fellow, -lack." and "Glad to see your mother's got a man to do it." -"Well," Mr. Summers said, "guess that's everyone. Old Man Warner make it?" -"Here," a voice said. and Mr. Summers nodded. -A sudden hush fell on the crowd as Mr. Summers cleared his throat and looked at the list. "All ready?" he -called. "Now, I'll read the names--heads of families first--and the men come up and take a paper out of -the box. Keep the paper folded in your hand without looking at it until everyone has had a turn. -Everything clear?" -The people had done it so many times that they only half listened to the directions: most of them were -quiet. wetting their lips. not looking around. Then Mr. Summers raised one hand high and said, "Adams." -A man disengaged himself from the crowd and came forward. "Hi. Steve." Mr. Summers said. and Mr. -Adams said. "Hi. Joe." They grinned at one another humorlessly and nervously. Then Mr. Adams reached -into the black box and took out a folded paper. He held it firmly by one corner as he turned and went -hastily back to his place in the crowd. where he stood a little apart from his family. not looking down at -his hand. -"Allen." Mr. Summers said. "Anderson.... Bentham." -"Seems like there's no time at all between lotteries any more." Mrs. Delacroix said to Mrs. Graves in the -back row. -"Seems like we got through with the last one only last week." -"Time sure goes fast.-- Mrs. Graves said. -file:///Users/carolynsigler/Desktop/lotry.html (3 of 8)1/23/2005 7:58:04 AM -The Lottery--Shirley Jackson -"Clark.... Delacroix" -"There goes my old man." Mrs. Delacroix said. She held her breath while her husband went forward. -"Dunbar," Mr. Summers said, and Mrs. Dunbar went steadily to the box while one of the women said. -"Go on. Janey," and another said, "There she goes." -"We're next." Mrs. Graves said. She watched while Mr. Graves came around from the side of the box, -greeted Mr. Summers gravely and selected a slip of paper from the box. By now, all through the crowd -there were men holding the small folded papers in their large hand. turning them over and over nervously -Mrs. Dunbar and her two sons stood together, Mrs. Dunbar holding the slip of paper. -"Harburt.... Hutchinson." -"Get up there, Bill," Mrs. Hutchinson said. and the people near her laughed. -"Jones." -"They do say," Mr. Adams said to Old Man Warner, who stood next to him, "that over in the north -village they're talking of giving up the lottery." -Old Man Warner snorted. "Pack of crazy fools," he said. "Listening to the young folks, nothing's good -enough for them. Next thing you know, they'll be wanting to go back to living in caves, nobody work any -more, live hat way for a while. Used to be a saying about 'Lottery in June, corn be heavy soon.' First thing -you know, we'd all be eating stewed chickweed and acorns. There's always been a lottery," he added -petulantly. "Bad enough to see young Joe Summers up there joking with everybody." -"Some places have already quit lotteries." Mrs. Adams said. -"Nothing but trouble in that," Old Man Warner said stoutly. "Pack of young fools." -"Martin." And Bobby Martin watched his father go forward. "Overdyke.... Percy." -"I wish they'd hurry," Mrs. Dunbar said to her older son. "I wish they'd hurry." -"They're almost through," her son said. -"You get ready to run tell Dad," Mrs. Dunbar said. -Mr. Summers called his own name and then stepped forward precisely and selected a slip from the box. -Then he called, "Warner." -"Seventy-seventh year I been in the lottery," Old Man Warner said as he went through the crowd. -"Seventy-seventh time." -file:///Users/carolynsigler/Desktop/lotry.html (4 of 8)1/23/2005 7:58:04 AM -The Lottery--Shirley Jackson -"Watson" The tall boy came awkwardly through the crowd. Someone said, "Don't be nervous, Jack," and -Mr. Summers said, "Take your time, son." -"Zanini." -After that, there was a long pause, a breathless pause, until Mr. Summers. holding his slip of paper in the -air, said, "All right, fellows." For a minute, no one moved, and then all the slips of paper were opened. -Suddenly, all the women began to speak at once, saving. "Who is it?," "Who's got it?," "Is it the -Dunbars?," "Is it the Watsons?" Then the voices began to say, "It's Hutchinson. It's Bill," "Bill -Hutchinson's got it." -"Go tell your father," Mrs. Dunbar said to her older son. -People began to look around to see the Hutchinsons. Bill Hutchinson was standing quiet, staring down at -the paper in his hand. Suddenly. Tessie Hutchinson shouted to Mr. Summers. "You didn't give him time -enough to take any paper he wanted. I saw you. It wasn't fair!" -"Be a good sport, Tessie." Mrs. Delacroix called, and Mrs. Graves said, "All of us took the same chance." -"Shut up, Tessie," Bill Hutchinson said. -"Well, everyone," Mr. Summers said, "that was done pretty fast, and now we've got to be hurrying a little -more to get done in time." He consulted his next list. "Bill," he said, "you draw for the Hutchinson -family. You got any other households in the Hutchinsons?" -"There's Don and Eva," Mrs. Hutchinson yelled. "Make them take their chance!" -"Daughters draw with their husbands' families, Tessie," Mr. Summers said gently. "You know that as -well as anyone else." -"It wasn't fair," Tessie said. -"I guess not, Joe." Bill Hutchinson said regretfully. "My daughter draws with her husband's family; that's -only fair. And I've got no other family except the kids." -"Then, as far as drawing for families is concerned, it's you," Mr. Summers said in explanation, "and as far -as drawing for households is concerned, that's you, too. Right?" -"Right," Bill Hutchinson said. -"How many kids, Bill?" Mr. Summers asked formally. -"Three," Bill Hutchinson said. -"There's Bill, Jr., and Nancy, and little Dave. And Tessie and me." -file:///Users/carolynsigler/Desktop/lotry.html (5 of 8)1/23/2005 7:58:04 AM -The Lottery--Shirley Jackson -"All right, then," Mr. Summers said. "Harry, you got their tickets back?" -Mr. Graves nodded and held up the slips of paper. "Put them in the box, then," Mr. Summers directed. -"Take Bill's and put it in." -"I think we ought to start over," Mrs. Hutchinson said, as quietly as she could. "I tell you it wasn't fair. -You didn't give him time enough to choose. Everybody saw that." -Mr. Graves had selected the five slips and put them in the box. and he dropped all the papers but those -onto the ground. where the breeze caught them and lifted them off. -"Listen, everybody," Mrs. Hutchinson was saying to the people around her. -"Ready, Bill?" Mr. Summers asked. and Bill Hutchinson, with one quick glance around at his wife and -children. nodded. -"Remember," Mr. Summers said. "take the slips and keep them folded until each person has taken one. -Harry, you help little Dave." Mr. Graves took the hand of the little boy, who came willingly with him up -to the box. "Take a paper out of the box, Davy." Mr. Summers said. Davy put his hand into the box and -laughed. "Take just one paper." Mr. Summers said. "Harry, you hold it for him." Mr. Graves took the -child's hand and removed the folded paper from the tight fist and held it while little Dave stood next to -him and looked up at him wonderingly. -"Nancy next," Mr. Summers said. Nancy was twelve, and her school friends breathed heavily as she went -forward switching her skirt, and took a slip daintily from the box "Bill, Jr.," Mr. Summers said, and Billy, -his face red and his feet overlarge, near knocked the box over as he got a paper out. "Tessie," Mr. -Summers said. She hesitated for a minute, looking around defiantly. and then set her lips and went up to -the box. She snatched a paper out and held it behind her. -"Bill," Mr. Summers said, and Bill Hutchinson reached into the box and felt around, bringing his hand -out at last with the slip of paper in it. -The crowd was quiet. A girl whispered, "I hope it's not Nancy," and the sound of the whisper reached the -edges of the crowd. -"It's not the way it used to be." Old Man Warner said clearly. "People ain't the way they used to be." -"All right," Mr. Summers said. "Open the papers. Harry, you open little Dave's." -Mr. Graves opened the slip of paper and there was a general sigh through the crowd as he held it up and -everyone could see that it was blank. Nancy and Bill. Jr.. opened theirs at the same time. and both -beamed and laughed. turning around to the crowd and holding their slips of paper above their heads. -"Tessie," Mr. Summers said. There was a pause, and then Mr. Summers looked at Bill Hutchinson, and -Bill unfolded his paper and showed it. It was blank. -file:///Users/carolynsigler/Desktop/lotry.html (6 of 8)1/23/2005 7:58:04 AM -The Lottery--Shirley Jackson -"It's Tessie," Mr. Summers said, and his voice was hushed. "Show us her paper. Bill." -Bill Hutchinson went over to his wife and forced the slip of paper out of her hand. It had a black spot on -it, the black spot Mr. Summers had made the night before with the heavy pencil in the coal company -office. Bill Hutchinson held it up, and there was a stir in the crowd. -"All right, folks." Mr. Summers said. "Let's finish quickly." -Although the villagers had forgotten the ritual and lost the original black box, they still remembered to -use stones. The pile of stones the boys had made earlier was ready; there were stones on the ground with -the blowing scraps of paper that had come out of the box Delacroix selected a stone so large she had to -pick it up with both hands and turned to Mrs. Dunbar. "Come on," she said. "Hurry up." -Mr. Dunbar had small stones in both hands, and she said. gasping for breath. "I can't run at all. You'll -have to go ahead and I'll catch up with you." -The children had stones already. And someone gave little Davy Hutchinson few pebbles. -Tessie Hutchinson was in the center of a cleared space by now, and she held her hands out desperately as -the villagers moved in on her. "It isn't fair," she said. A stone hit her on the side of the head. Old Man -Warner was saying, "Come on, come on, everyone." Steve Adams was in the front of the crowd of -villagers, with Mrs. Graves beside him. -"It isn't fair, it isn't right," Mrs. Hutchinson screamed, and then they were upon her. \ No newline at end of file diff --git a/cli/.gitignore b/cli/.gitignore deleted file mode 100644 index 94db6df..0000000 --- a/cli/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.schema* -data.db* -files/ diff --git a/cli/Cargo.lock b/cli/Cargo.lock deleted file mode 100644 index 6495a2a..0000000 --- a/cli/Cargo.lock +++ /dev/null @@ -1,2857 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[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 = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - -[[package]] -name = "anstream" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "anstyle-parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "anyhow" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" - -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "atoi" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bfsp" -version = "0.1.0" -dependencies = [ - "anyhow", - "blake3", - "bytes", - "chacha20poly1305", - "macaroon", - "prost", - "prost-build", - "regex", - "serde", - "serde_derive", - "sqlx", - "tokio", - "uuid", - "zstd", -] - -[[package]] -name = "bitflags" -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" -dependencies = [ - "serde", -] - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "blake3" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "rayon", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" - -[[package]] -name = "bytecheck" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - -[[package]] -name = "clap" -version = "4.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "cli_enc" -version = "0.1.0" -dependencies = [ - "anyhow", - "bfsp", - "clap", - "directories-next", - "fern", - "futures", - "humantime", - "log", - "reqwest", - "rkyv", - "sqlx", - "tokio", - "wasm-timer", - "web-sys", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "const-oid" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" - -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - -[[package]] -name = "cpufeatures" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "der" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "directories-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -dependencies = [ - "serde", -] - -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "etcetera" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" -dependencies = [ - "cfg-if", - "home", - "windows-sys", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fern" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" -dependencies = [ - "log", -] - -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "futures-core", - "futures-sink", - "spin 0.9.8", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -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-intrusive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot 0.12.1", -] - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-util" -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", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - -[[package]] -name = "h2" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.6", -] - -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" -dependencies = [ - "ahash 0.8.6", - "allocator-api2", -] - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.0", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin 0.5.2", -] - -[[package]] -name = "libc" -version = "0.2.150" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "libsodium-sys" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b779387cd56adfbc02ea4a668e704f729be8d6a6abd2c27ca5ee537849a92fd" -dependencies = [ - "cc", - "libc", - "pkg-config", - "walkdir", -] - -[[package]] -name = "libsqlite3-sys" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" - -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" - -[[package]] -name = "macaroon" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b15778101dd1d3a58a95fd2af33821b38bc44a408bcf03e0e5e194f42c08050" -dependencies = [ - "base64 0.13.1", - "log", - "serde", - "serde_json", - "sodiumoxide", -] - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" -dependencies = [ - "libc", - "wasi", - "windows-sys", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[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", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.3.5", - "smallvec", - "windows-targets", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - -[[package]] -name = "petgraph" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2", - "syn 2.0.32", -] - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5a410fc7882af66deb8d01d01737353cf3ad6204c408177ba494291a626312" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa3d084c8704911bfefb2771be2f9b6c5c0da7343a71e0021ee3c665cada738" -dependencies = [ - "bytes", - "heck", - "itertools", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 2.0.32", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065717a5dfaca4a83d2fe57db3487b311365200000551d7a364e715dbf4346bc" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "prost-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8339f32236f590281e2f6368276441394fcd1b2133b549cc895d0ae80f2f9a52" -dependencies = [ - "prost", -] - -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "quote" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[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", -] - -[[package]] -name = "regex" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "rend" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "reqwest" -version = "0.11.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" -dependencies = [ - "base64 0.21.5", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "system-configuration", - "tokio", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", -] - -[[package]] -name = "ring" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" -dependencies = [ - "cc", - "getrandom", - "libc", - "spin 0.9.8", - "untrusted", - "windows-sys", -] - -[[package]] -name = "rkyv" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" -dependencies = [ - "bitvec", - "bytecheck", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rsa" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core", - "signature 2.2.0", - "spki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.38.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rustls" -version = "0.21.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.5", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - -[[package]] -name = "serde" -version = "1.0.173" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91f70896d6720bc714a4a57d22fc91f1db634680e65c8efe13323f1fa38d53f" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.173" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6250dde8342e0232232be9ca3db7aa40aceb5a3e5dd9bddbc00d99a007cde49" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "serde_json" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core", -] - -[[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - -[[package]] -name = "slab" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "sodiumoxide" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e26be3acb6c2d9a7aac28482586a7856436af4cfe7100031d219de2d2ecb0028" -dependencies = [ - "ed25519", - "libc", - "libsodium-sys", - "serde", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sqlformat" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" -dependencies = [ - "itertools", - "nom", - "unicode_categories", -] - -[[package]] -name = "sqlx" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" -dependencies = [ - "sqlx-core", - "sqlx-macros", - "sqlx-mysql", - "sqlx-postgres", - "sqlx-sqlite", -] - -[[package]] -name = "sqlx-core" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" -dependencies = [ - "ahash 0.8.6", - "atoi", - "byteorder", - "bytes", - "crc", - "crossbeam-queue", - "dotenvy", - "either", - "event-listener", - "futures-channel", - "futures-core", - "futures-intrusive", - "futures-io", - "futures-util", - "hashlink", - "hex", - "indexmap", - "log", - "memchr", - "once_cell", - "paste", - "percent-encoding", - "serde", - "serde_json", - "sha2", - "smallvec", - "sqlformat", - "thiserror", - "tokio", - "tokio-stream", - "tracing", - "url", -] - -[[package]] -name = "sqlx-macros" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" -dependencies = [ - "proc-macro2", - "quote", - "sqlx-core", - "sqlx-macros-core", - "syn 1.0.109", -] - -[[package]] -name = "sqlx-macros-core" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" -dependencies = [ - "dotenvy", - "either", - "heck", - "hex", - "once_cell", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-mysql", - "sqlx-sqlite", - "syn 1.0.109", - "tempfile", - "tokio", - "url", -] - -[[package]] -name = "sqlx-mysql" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" -dependencies = [ - "atoi", - "base64 0.21.5", - "bitflags 2.4.1", - "byteorder", - "bytes", - "crc", - "digest", - "dotenvy", - "either", - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "generic-array", - "hex", - "hkdf", - "hmac", - "itoa", - "log", - "md-5", - "memchr", - "once_cell", - "percent-encoding", - "rand", - "rsa", - "serde", - "sha1", - "sha2", - "smallvec", - "sqlx-core", - "stringprep", - "thiserror", - "tracing", - "whoami", -] - -[[package]] -name = "sqlx-postgres" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" -dependencies = [ - "atoi", - "base64 0.21.5", - "bitflags 2.4.1", - "byteorder", - "crc", - "dotenvy", - "etcetera", - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "hex", - "hkdf", - "hmac", - "home", - "itoa", - "log", - "md-5", - "memchr", - "once_cell", - "rand", - "serde", - "serde_json", - "sha1", - "sha2", - "smallvec", - "sqlx-core", - "stringprep", - "thiserror", - "tracing", - "whoami", -] - -[[package]] -name = "sqlx-sqlite" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" -dependencies = [ - "atoi", - "flume", - "futures-channel", - "futures-core", - "futures-executor", - "futures-intrusive", - "futures-util", - "libsqlite3-sys", - "log", - "percent-encoding", - "serde", - "sqlx-core", - "tracing", - "url", -] - -[[package]] -name = "stringprep" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" -dependencies = [ - "finl_unicode", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "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 = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.4.1", - "rustix", - "windows-sys", -] - -[[package]] -name = "thiserror" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" -dependencies = [ - "autocfg", - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot 0.12.1", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "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", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - -[[package]] -name = "unicode-ident" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "uuid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" -dependencies = [ - "getrandom", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.32", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" - -[[package]] -name = "wasm-timer" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" -dependencies = [ - "futures", - "js-sys", - "parking_lot 0.11.2", - "pin-utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "whoami" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zerocopy" -version = "0.7.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" - -[[package]] -name = "zstd" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/cli/Cargo.toml b/cli/Cargo.toml deleted file mode 100644 index 11ceefe..0000000 --- a/cli/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "cli_enc" -version = "0.1.0" -edition = "2021" - - -[dependencies] -anyhow = "1" -bfsp = { path = "../bfsp" } -humantime = "2" -fern = "0.6" -log = "0.4" -sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio"] } -clap = { version = "4", features = ["derive"] } -futures = "0.3" -reqwest = { version = "0.11", default-features = false, features = [ - "json", - "rustls-tls", -] } -tokio = { version = "1", features = ["full"] } diff --git a/cli/build.rs b/cli/build.rs deleted file mode 100644 index d506869..0000000 --- a/cli/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -// generated by `sqlx migrate build-script` -fn main() { - // trigger recompilation when a new migration is added - println!("cargo:rerun-if-changed=migrations"); -} diff --git a/cli/fonts/icons.ttf b/cli/fonts/icons.ttf deleted file mode 100644 index 4498299..0000000 Binary files a/cli/fonts/icons.ttf and /dev/null differ diff --git a/cli/migrations/20230810233647_create_file_header.sql b/cli/migrations/20230810233647_create_file_header.sql deleted file mode 100644 index 5c9f7ed..0000000 --- a/cli/migrations/20230810233647_create_file_header.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE files -( -file_path text primary key not null, -hash text not null, -chunk_size int not null, -chunks int not null -) diff --git a/cli/migrations/20230811151656_create_chunks_table.sql b/cli/migrations/20230811151656_create_chunks_table.sql deleted file mode 100644 index 03a2820..0000000 --- a/cli/migrations/20230811151656_create_chunks_table.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE chunks ( -hash text primary key unique not null, -id text unique not null, -indice int not null, -uploaded boolean default false, -chunk_size int not null, -file_hash text not null, -nonce blob not null -) diff --git a/cli/migrations/20231006201309_store_enc_key.sql b/cli/migrations/20231006201309_store_enc_key.sql deleted file mode 100644 index de6c256..0000000 --- a/cli/migrations/20231006201309_store_enc_key.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Add migration script here -CREATE table enc_keys ( -username text primary key default null, -enc_key blob not null -) diff --git a/cli/migrations/20231013033720_create_keys.sql b/cli/migrations/20231013033720_create_keys.sql deleted file mode 100644 index f581aa1..0000000 --- a/cli/migrations/20231013033720_create_keys.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table keys ( -username text primary key not null, -enc_key blob not null, -macaroon text not null -) diff --git a/cli/rustfmt.toml b/cli/rustfmt.toml deleted file mode 100644 index 3a26366..0000000 --- a/cli/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -edition = "2021" diff --git a/cli/src/main.rs b/cli/src/main.rs deleted file mode 100644 index 67ae698..0000000 --- a/cli/src/main.rs +++ /dev/null @@ -1,698 +0,0 @@ -use anyhow::{anyhow, Context, Error}; -use bfsp::auth::{Authentication, CreateUserRequest, LoginRequest}; -use bfsp::cli::{compressed_encrypted_chunk_from_file, use_parallel_hasher, FileHeader}; -use bfsp::file_server_message::{ - ChunksUploadedQuery, DownloadChunkQuery, Message, UploadChunkQuery, -}; -use bfsp::{download_chunk_resp, ChunkHash, Message as MessageTrait}; -use sqlx::{Row, SqlitePool}; -use std::collections::{HashMap, HashSet}; -use std::env; -use std::fmt::Display; -use std::path::Path; - -use anyhow::Result; -use bfsp::{ - hash_chunk, hash_file, parallel_hash_chunk, ChunkID, ChunkMetadata, ChunksUploadedQueryResp, - DownloadChunkResp, EncryptionKey, FileHash, FileServerMessage, UploadChunkResp, -}; -use log::{debug, trace}; -use tokio::fs::{self, canonicalize, File, OpenOptions}; -use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; -use tokio::net::TcpStream; - -use clap::{Parser, Subcommand}; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - #[command(subcommand)] - command: Commands, -} - -#[derive(Subcommand, Debug)] -enum Commands { - Upload { - file_path: String, - }, - Download { - file_path: String, - download_to: Option, - }, - Signup { - email: String, - password: String, - }, - Login { - email: String, - password: String, - }, -} - -#[tokio::main] -async fn main() { - fern::Dispatch::new() - .format(|out, msg, record| { - out.finish(format_args!( - "[{} {} {}] {}", - humantime::format_rfc3339(std::time::SystemTime::now()), - record.level(), - record.target(), - msg - )) - }) // Add blanket level filter - - .level(log::LevelFilter::Trace) - .level_for("sqlx", log::LevelFilter::Warn) - .level_for("hyper", log::LevelFilter::Warn) - // - and per-module overrides - // Output to stdout, files, and other Dispatch configurations - .chain(std::io::stdout()) - .chain(fern::log_file("output.log").unwrap()) - // Apply globally - .apply() - .unwrap(); - - let pool_url = |_| { - format!( - "sqlite:{}/data.db", - env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()) - ) - }; - let pool = sqlx::SqlitePool::connect(&env::var("DATABASE_URL").unwrap_or_else(pool_url)) - .await - .unwrap(); - - sqlx::migrate!().run(&pool).await.unwrap(); - - let client = reqwest::ClientBuilder::new().build().unwrap(); - - let args = Args::parse(); - - match args.command { - Commands::Upload { file_path } => { - let (key, macaroon): (EncryptionKey, String) = - match sqlx::query("select enc_key, macaroon from keys") - .fetch_optional(&pool) - .await - .unwrap() - { - Some(key_info) => ( - key_info.get::, _>("enc_key").try_into().unwrap(), - key_info.get::("macaroon"), - ), - None => { - println!("Please login."); - return; - } - }; - - let mut sock = TcpStream::connect("127.0.0.1:9999").await.unwrap(); - - if let Err(err) = add_file(&file_path, &pool).await { - debug!("Error adding file: {err:?}"); - - if let Some(err) = err.downcast_ref::() { - match err { - AddFileRecoverableErr::FileAlreadyAdded => (), - AddFileRecoverableErr::ChunkAlreadyAdded => (), - } - } else { - panic!("{err}"); - } - } - - let file_headers = file_headers_from_path(&file_path, &pool).await.unwrap(); - let file_header = file_headers.first().unwrap(); - - upload_file(&file_path, file_header, &mut sock, &key, macaroon) - .await - .unwrap() - } - Commands::Download { - file_path, - download_to, - } => { - let (key, macaroon): (EncryptionKey, String) = - match sqlx::query("select enc_key, macaroon from keys") - .fetch_optional(&pool) - .await - .unwrap() - { - Some(key_info) => ( - key_info.get::, _>("enc_key").try_into().unwrap(), - key_info.get::("macaroon"), - ), - None => { - println!("Please login."); - return; - } - }; - - let mut sock = TcpStream::connect("127.0.0.1:9999").await.unwrap(); - let file_headers = file_headers_from_path(&file_path, &pool).await.unwrap(); - let file_header = file_headers.first().ok_or("File not found").unwrap(); - - download_file( - &file_header, - download_to.unwrap_or_else(|| "./".to_string()), - &mut sock, - &key, - macaroon, - ) - .await - .unwrap(); - } - Commands::Signup { email, password } => { - let response = client - .post("http://127.0.0.1:3000/create_user") - .json(&CreateUserRequest { email, password }) - .send() - .await - .unwrap(); - - let response_status = response.status(); - - if response_status.is_success() { - println!("Successfully registered! Please sign in"); - } else { - let response_text = response.text().await.unwrap(); - println!("Error when trying to register: '{}'", response_text); - } - } - Commands::Login { email, password } => { - let response = client - .post("http://127.0.0.1:3000/login_user") - .json(&LoginRequest { email, password }) - .send() - .await - .unwrap(); - - let response_status = response.status(); - let response_text = response.text().await.unwrap(); - - if response_status.is_success() { - let key = EncryptionKey::new(); - sqlx::query("insert into keys (enc_key, username, macaroon) values ( ?, ?, ? )") - .bind(key) - .bind("billy") - .bind(response_text) - .execute(&pool) - .await - .unwrap(); - - println!("Successfully logged in!!!") - } else { - println!("Got response: '{response_text}' with status: '{response_status}'"); - } - } - } -} - -pub async fn query_chunks_uploaded( - file_hash: &FileHash, - sock: &mut TcpStream, - pool: &SqlitePool, - macaroon: String, -) -> Result { - trace!("Querying chunks uploaded"); - - let chunk_ids = sqlx::query("select id from chunks where file_hash = ?") - .bind(file_hash) - .fetch_all(pool) - .await - .with_context(|| format!("Failed to get chunk IDs for file hash {}", file_hash))? - .into_iter() - .map(|chunk_info| chunk_info.get::("id").try_into()) - .collect::>>()?; - - let msg = FileServerMessage { - auth: Some(Authentication { macaroon }), - message: Some(Message::ChunksUploadedQuery(ChunksUploadedQuery { - chunk_ids: chunk_ids - .into_iter() - .map(|id| id.to_bytes().to_vec()) - .collect(), - })), - }; - - sock.write_all(msg.to_bytes().as_slice()).await?; - - let resp_len = sock.read_u32_le().await?; - let mut resp_bytes = vec![0; resp_len as usize]; - sock.read_exact(&mut resp_bytes).await?; - - let resp = ChunksUploadedQueryResp::decode(resp_bytes.as_slice()) - .map_err(|_| anyhow!("Error deserializing ChunksUploadedQueryResp"))?; - - trace!("Finished querying chunks uploaded"); - Ok(resp) -} - -#[derive(Debug)] -pub enum AddFileRecoverableErr { - FileAlreadyAdded, - ChunkAlreadyAdded, -} - -impl Display for AddFileRecoverableErr { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - AddFileRecoverableErr::FileAlreadyAdded => "File already added", - AddFileRecoverableErr::ChunkAlreadyAdded => "Chunk already added", - }) - } -} - -impl std::error::Error for AddFileRecoverableErr {} - -// TODO: delete unused chunks on server -pub async fn update_file(file_path: &str, file: &mut File, pool: &SqlitePool) -> Result<()> { - trace!("Updating file {file_path}"); - - let file_path = fs::canonicalize(file_path).await?; - let file_path = file_path.to_str().unwrap(); - - let original_file_hash: FileHash = sqlx::query("select hash from files where file_path = ?") - .bind(file_path) - .fetch_one(pool) - .await - .with_context(|| "Error getting file id for updating file")? - .get::("hash") - .try_into()?; - - let file_header = FileHeader::from_file(file).await?; - file.rewind().await?; - let file_hash = hash_file(file).await?; - file.rewind().await?; - - let num_chunks: i64 = file_header.chunks.len().try_into().unwrap(); - - sqlx::query("update files set hash = ?, chunk_size = ?, chunks = ? where file_path = ?") - .bind(file_hash) - .bind(file_header.chunk_size) - .bind(num_chunks) - .bind(file_path) - .execute(pool) - .await - .map_err(|err| match err { - sqlx::Error::Database(err) => match err.kind() { - sqlx::error::ErrorKind::UniqueViolation => { - Error::new(AddFileRecoverableErr::FileAlreadyAdded) - } - _ => anyhow!("Unknown database error: {err:#}"), - }, - _ => anyhow!("Unknown database error: {err:#}"), - })?; - - trace!("Deleting chunks for file {file_path}"); - - sqlx::query("delete from chunks where file_hash = ?") - .bind(original_file_hash) - .execute(pool) - .await?; - - trace!("Inserting chunks for file {file_path}"); - - for (chunk_id, chunk) in file_header.chunks.iter() { - sqlx::query( - r#"insert into chunks - (hash, id, file_hash, chunk_size) - values ( ?, ?, ?, ? ) - "#, - ) - .bind(&chunk.hash) - .bind(chunk_id) - .bind(&file_header.hash) - .bind(chunk.size) - .execute(pool) - .await?; - } - - Ok(()) -} - -pub async fn add_file(file_path: &str, pool: &SqlitePool) -> Result<()> { - trace!("Adding file {file_path}"); - - let file_path = fs::canonicalize(file_path).await?; - let file_path = file_path.to_str().unwrap(); - - let mut file = fs::File::open(file_path) - .await - .with_context(|| format!("Failed to read file {file_path} for adding"))?; - let file_header = FileHeader::from_file(&mut file).await?; - - file.rewind().await?; - - let file_hash = hash_file(&mut file).await?; - file.rewind().await?; - - let num_chunks: i64 = file_header.chunks.len().try_into().unwrap(); - - sqlx::query( - r#"insert into files - (file_path, hash, chunk_size, chunks) - values ( ?, ?, ?, ? ) - "#, - ) - .bind(file_path) - .bind(&file_hash) - .bind(file_header.chunk_size) - .bind(num_chunks) - .execute(pool) - .await - .map_err(|err| match err { - sqlx::Error::Database(err) => match err.kind() { - sqlx::error::ErrorKind::UniqueViolation => { - Error::new(AddFileRecoverableErr::FileAlreadyAdded) - } - _ => anyhow!("Unknown database error: {err:#}"), - }, - _ => anyhow!("Unknown database error: {err:#}"), - })?; - - trace!("Inserting chunks"); - - //TODO: batch job this - for (chunk_id, chunk) in file_header.chunks.iter() { - let indice: i64 = (*file_header.chunk_indices.get(&chunk_id).unwrap()) - .try_into() - .unwrap(); - - sqlx::query( - r#"insert into chunks - (hash, id, chunk_size, indice, file_hash, nonce ) - values ( ?, ?, ?, ?, ?, ? ) - "#, - ) - .bind(ChunkHash::from_bytes(chunk.clone().hash.try_into().unwrap()).to_string()) - .bind(chunk_id) - .bind(chunk.size) - .bind(indice) - .bind(&file_hash) - .bind(&chunk.nonce) - .execute(pool) - .await - .map_err(|err| match err { - sqlx::Error::Database(err) => match err.kind() { - sqlx::error::ErrorKind::UniqueViolation => { - Error::new(AddFileRecoverableErr::ChunkAlreadyAdded) - } - _ => anyhow!("Unknown database error: {err:#}"), - }, - _ => anyhow!("Unknown database error: {err:#}"), - })?; - } - - Ok(()) -} - -pub async fn upload_file( - file_path: &str, - file_header: &FileHeader, - sock: &mut TcpStream, - key: &EncryptionKey, - macaroon: String, -) -> Result<()> { - trace!("Uploading file"); - - // TODO: optimize with query_chunks_uploaded - let chunks_to_upload = file_header.chunks.values(); - - trace!("Uploading {} chunks", chunks_to_upload.len()); - let mut file = OpenOptions::new() - .read(true) - .open(file_path) - .await - .with_context(|| "Reading file for upload")?; - - for chunk_meta in chunks_to_upload.into_iter() { - let chunk_id = ChunkID::from_bytes(chunk_meta.clone().id.try_into().unwrap()); - trace!("Uploading chunk {chunk_id}"); - - let chunk = - compressed_encrypted_chunk_from_file(file_header, &mut file, chunk_id, key).await?; - - let msg = FileServerMessage { - auth: Some(Authentication { - macaroon: macaroon.clone(), - }), - message: Some(Message::UploadChunkQuery(UploadChunkQuery { - chunk_metadata: Some(chunk_meta.clone()), - chunk, - })), - }; - - trace!("Writing to socket"); - sock.write_all(msg.to_bytes().as_slice()).await?; - - trace!("Reading response"); - let resp_len = sock.read_u32_le().await?; - - let mut resp_bytes = vec![0; resp_len.try_into().unwrap()]; - sock.read_exact(&mut resp_bytes).await?; - - let resp = UploadChunkResp::decode(resp_bytes.as_slice()) - .map_err(|_| anyhow!("Error deserializing UploadChunkResp"))?; - } - - trace!("Uploaded file"); - - Ok(()) -} - -pub async fn download_file + Display>( - file_header: &FileHeader, - path_to_download_to: P, - sock: &mut TcpStream, - key: &EncryptionKey, - macaroon: String, -) -> Result<()> { - trace!("Downloading file {path_to_download_to}"); - - trace!("Creating or opening file {path_to_download_to}"); - - let mut file = OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(&path_to_download_to) - .await?; - - trace!("Opened file {path_to_download_to}"); - - let use_parallel_hasher = use_parallel_hasher(file_header.chunk_size as usize); - let hash_chunk_fn = match use_parallel_hasher { - true => parallel_hash_chunk, - false => hash_chunk, - }; - - debug!("File header chunks len: {}", file_header.chunks.len()); - - // TODO: can this be optimized by seing which chunks have changed - for chunk_id in file_header.chunks.keys() { - trace!("Requesting chunk {chunk_id}"); - - let msg = FileServerMessage { - auth: Some(Authentication { - macaroon: macaroon.clone(), - }), - message: Some(Message::DownloadChunkQuery(DownloadChunkQuery { - chunk_id: chunk_id.to_bytes().to_vec(), - })), - }; - - sock.write_all(msg.to_bytes().as_slice()).await?; - - let resp_len = sock.read_u32_le().await?; - let mut resp_bytes = vec![0; resp_len.try_into().unwrap()]; - sock.read_exact(&mut resp_bytes).await?; - - let resp = DownloadChunkResp::decode(resp_bytes.as_slice())?; - let (chunk_metadata, mut chunk_buf): (ChunkMetadata, Vec) = match resp.response.unwrap() - { - download_chunk_resp::Response::ChunkData(chunk_data) => { - (chunk_data.chunk_metadata.unwrap(), chunk_data.chunk) - } - download_chunk_resp::Response::Err(err) => todo!("{err}"), - }; - - debug!( - "Encrypted chunk {} hash {}", - ChunkID::from_bytes(chunk_metadata.id.clone().try_into().unwrap()), - hash_chunk_fn(&chunk_buf).to_string() - ); - - key.decrypt_chunk_in_place(&mut chunk_buf, &chunk_metadata) - .with_context(|| "Error decrypting chunk")?; - - let chunk_hash = hash_chunk_fn(&chunk_buf); - let chunk_metadata_hash = ChunkHash::from_bytes(chunk_metadata.hash.try_into().unwrap()); - - // Check the hash of the chunk - if chunk_hash != chunk_metadata_hash { - todo!("Sent bad chunk") - } - - // Copy the chunk into the file - let chunk_byte_index = chunk_metadata.indice * file_header.chunk_size as u64; - - file.seek(std::io::SeekFrom::Start(chunk_byte_index)) - .await - .with_context(|| { - anyhow!("Error encounted while seeking to {chunk_byte_index} in file") - })?; - file.write_all(&chunk_buf) - .await - .with_context(|| "Error while writing chunk to file")?; - } - - debug!("Finished downloading file {path_to_download_to}"); - - Ok(()) -} - -/// Ensures that the file given and file header as exists in the database are the same -async fn validate_file(file_path: &str, pool: &SqlitePool) -> Result { - let file_info = - sqlx::query("select file_path, hash, chunk_size from files where file_path = ?") - .bind(file_path) - .fetch_one(pool) - .await?; - - let chunk_size: u32 = file_info.get("chunk_size"); - let file_hash: FileHash = file_info.get::("hash").try_into()?; - - // TODO: return cstuom error for when file isn't added - let chunks = - sqlx::query("select hash, id, chunk_size, indice, nonce from chunks where file_hash = ?") - .bind(&file_hash) - .fetch_all(pool) - .await - .with_context(|| "Error querying db for chunks: ")?; - - let chunks = chunks.into_iter().map(|chunk| ChunkMetadata { - id: chunk.get::("id").try_into().unwrap(), - hash: chunk.get::("hash").try_into().unwrap(), - size: chunk.get::("chunk_size"), - indice: chunk.get::("indice").try_into().unwrap(), - nonce: chunk.get::, _>("nonce").try_into().unwrap(), - }); - - let chunk_indices: HashMap = - sqlx::query("select indice, id from chunks where file_hash = ?") - .bind(&file_hash) - .fetch_all(pool) - .await - .with_context(|| "Error querying db for chunk indicecs: ")? - .into_iter() - .map(|chunk_info| { - let chunk_id: ChunkID = chunk_info.get::("id").try_into().unwrap(); - let chunk_indice: u64 = chunk_info.get::("indice").try_into().unwrap(); - - (chunk_id, chunk_indice) - }) - .collect(); - let chunks = chunks - .into_iter() - .map(|chunk| { - ( - ChunkID::from_bytes(chunk.id.clone().try_into().unwrap()), - chunk, - ) - }) - .collect(); - - let file_header_sql = FileHeader { - hash: file_hash, - chunk_size, - chunks, - chunk_indices, - }; - - let mut file = File::open(file_path).await?; - let file_header = FileHeader::from_file(&mut file).await?; - - debug_assert_eq!(file_header_sql.chunk_indices, file_header.chunk_indices); - debug_assert_eq!(file_header_sql.chunks, file_header.chunks); - - return Ok(file_header_sql == file_header); -} - -async fn file_headers_from_path(path: &str, pool: &SqlitePool) -> Result> { - let path = canonicalize(path).await?; - let path = path.to_string_lossy(); - - futures::future::try_join_all( - sqlx::query("select hash, file_path from files where file_path = ?") - .bind(path) - .fetch_all(pool) - .await? - .into_iter() - .map(|file_info| async move { - let file_hash: FileHash = file_info.get::("hash").try_into()?; - let file_path = file_info.get::<&str, _>("file_path"); - - let chunks = sqlx::query( - "select hash, id, chunk_size, indice, nonce from chunks where file_hash = ?", - ) - .bind(&file_hash) - .fetch_all(pool) - .await - .with_context(|| "Error querying db for chunks: ")?; - - let chunks = chunks.into_iter().map(|chunk| { - let chunk_id: ChunkID = chunk.get::("id").try_into().unwrap(); - let chunk_hash: ChunkHash = chunk.get::("hash").try_into().unwrap(); - ChunkMetadata { - id: chunk_id.to_bytes().to_vec(), - hash: chunk_hash.to_bytes().to_vec(), - size: chunk.get::("chunk_size"), - indice: chunk.get::("indice").try_into().unwrap(), - nonce: chunk.get::, _>("nonce").try_into().unwrap(), - } - }); - - let chunk_indices: HashMap = - sqlx::query("select indice, id from chunks where file_hash = ?") - .bind(&file_hash) - .fetch_all(pool) - .await - .with_context(|| "Error querying db for chunk indicecs: ")? - .into_iter() - .map(|chunk_info| { - let chunk_id: ChunkID = - chunk_info.get::("id").try_into().unwrap(); - let chunk_indice: u64 = - chunk_info.get::("indice").try_into().unwrap(); - - (chunk_id, chunk_indice) - }) - .collect(); - - let chunks = chunks - .into_iter() - .map(|chunk| { - ( - ChunkID::from_bytes(chunk.id.clone().try_into().unwrap()), - chunk, - ) - }) - .collect(); - - let file_info = - sqlx::query("select hash, chunk_size from files where file_path = ?") - .bind(file_path) - .fetch_one(pool) - .await?; - - Ok(FileHeader { - hash: file_info.get::("hash").try_into()?, - chunk_size: file_info.get::("chunk_size"), - chunks, - chunk_indices, - }) - }), - ) - .await -} diff --git a/flake.lock b/flake.lock index be04d30..be001f3 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ ] }, "locked": { - "lastModified": 1700327093, - "narHash": "sha256-OgYvlBABxJYWhZ/HBd0bPVcIEkT+xDhDCpRYqtVhYWY=", + "lastModified": 1701622587, + "narHash": "sha256-o3XhxCCyrUHZ0tlta2W7/MuXzy+n0+BUt3rKFK3DIK4=", "owner": "ipetkov", "repo": "crane", - "rev": "ae7cd510e508ee03d792005c2f1c0a3ff25ecb80", + "rev": "c09d2cbe84cc2adfe1943cb2a0b55a71c835ca9a", "type": "github" }, "original": { @@ -25,11 +25,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1694529238, - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { @@ -58,11 +58,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1700108881, - "narHash": "sha256-+Lqybl8kj0+nD/IlAWPPG/RDTa47gff9nbei0u7BntE=", + "lastModified": 1701693815, + "narHash": "sha256-7BkrXykVWfkn6+c1EhFA3ko4MLi3gVG0p9G96PNnKTM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7414e9ee0b3e9903c24d3379f577a417f0aae5f1", + "rev": "09ec6a0881e1a36c29d67497693a67a16f4da573", "type": "github" }, "original": { @@ -102,11 +102,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1700273673, - "narHash": "sha256-0XD4JvrQiZ9BDFdH3VTwqZVXTYzOfS7DVblvqHBnWgE=", + "lastModified": 1701915404, + "narHash": "sha256-+aR/adz9lNglnCzrCh30FSj+Ee+liy8gwOKtS7ll9yY=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "616074a1b2a71bbe44da4cc29a64255aecb8d541", + "rev": "670ae43e7e5e7cf90b873cea596941d2e24e9c2c", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 2943a82..ce30c78 100644 --- a/flake.nix +++ b/flake.nix @@ -23,7 +23,7 @@ rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; craneLib = crane.lib.${system}.overrideToolchain rustToolchain; my-crate = craneLib.buildPackage { - src = craneLib.cleanCargoSource (craneLib.path ./fs); + src = craneLib.cleanCargoSource (craneLib.path ./.); cargoVendorDir = craneLib.vendorCargoDeps { cargoLock = ./Cargo.lock; }; buildInputs = with pkgs; [ diff --git a/fs/Cargo.toml b/fs/Cargo.toml deleted file mode 100644 index 6a0854f..0000000 --- a/fs/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "file_server" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow = { version = "1" } -tokio = { version = "1", features = [ - "net", - "fs", - "macros", - "io-util", - "rt-multi-thread", -] } -log = { version = "0.4" } -fern = { version = "0.6", features = ["colored"] } -humantime = "2" -sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] } -rand = "0.8" -bfsp = { path = "../bfsp" } -async-trait = { version = "0.1" } -once_cell = "1" -futures = { version = "0.3", features = ["executor"] } -macaroon = "0.3" - diff --git a/fs/flake.lock b/fs/flake.lock deleted file mode 100644 index 871d50c..0000000 --- a/fs/flake.lock +++ /dev/null @@ -1,151 +0,0 @@ -{ - "nodes": { - "crane": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1699218802, - "narHash": "sha256-5l0W4Q7z7A4BCstaF5JuBqXOVrZ3Vqst5+hUnP7EdUc=", - "owner": "ipetkov", - "repo": "crane", - "rev": "2d6c2aaff5a05e443eb15efddc21f9c73720340c", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "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" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1699186365, - "narHash": "sha256-Pxrw5U8mBsL3NlrJ6q1KK1crzvSUcdfwb9083sKDrcU=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "a0b3b06b7a82c965ae0bb1d59f6e386fe755001d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1681358109, - "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-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_2", - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1699323235, - "narHash": "sha256-ZFRItRv0dDSzsfpqSjj9qWM/SA1kRrOk6R04qhBZuxM=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "8a9d6f544c08ee898c7f3761cc9587be7565db5e", - "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" - } - }, - "systems_2": { - "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/fs/rustfmt.toml b/fs/rustfmt.toml deleted file mode 100644 index 3a26366..0000000 --- a/fs/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -edition = "2021" diff --git a/fs/migrations/20231018041636_chunks.sql b/migrations/20231018041636_chunks.sql similarity index 100% rename from fs/migrations/20231018041636_chunks.sql rename to migrations/20231018041636_chunks.sql diff --git a/auth/rustfmt.toml b/rustfmt.toml similarity index 100% rename from auth/rustfmt.toml rename to rustfmt.toml diff --git a/fs/src/db.rs b/src/db.rs similarity index 97% rename from fs/src/db.rs rename to src/db.rs index 73abc98..7f5c0d3 100644 --- a/fs/src/db.rs +++ b/src/db.rs @@ -84,7 +84,7 @@ impl ChunkDatabase for SqliteDB { hash: chunk_hash.to_bytes().to_vec(), size: chunk_info.get::("chunk_size"), indice: chunk_info.get::("indice").try_into().unwrap(), - nonce: chunk_info.get::, _>("nonce").try_into().unwrap(), + nonce: chunk_info.get::, _>("nonce"), } })) } diff --git a/fs/src/io.rs b/src/io.rs similarity index 100% rename from fs/src/io.rs rename to src/io.rs diff --git a/fs/src/main.rs b/src/main.rs similarity index 87% rename from fs/src/main.rs rename to src/main.rs index e1f96ec..cc96a82 100644 --- a/fs/src/main.rs +++ b/src/main.rs @@ -12,12 +12,12 @@ use std::{ use anyhow::Result; use bfsp::PrependLen; use bfsp::{ - auth::{self, ExpirationCaveat, UsernameCaveat}, + auth::{EmailCaveat, ExpirationCaveat}, chunks_uploaded_query_resp::{ChunkUploaded, ChunksUploaded}, download_chunk_resp::ChunkData, file_server_message::Message::{ChunksUploadedQuery, DownloadChunkQuery, UploadChunkQuery}, - AuthErr, ChunkID, ChunkMetadata, ChunkNotFound, ChunksUploadedQueryResp, DownloadChunkResp, - FileServerMessage, Message, + AuthErr, ChunkID, ChunkMetadata, ChunksUploadedQueryResp, DownloadChunkResp, FileServerMessage, + Message, }; use log::{debug, info, trace}; use macaroon::{ByteString, Caveat, Macaroon, MacaroonKey, Verifier}; @@ -75,11 +75,11 @@ async fn main() -> Result<()> { todo!("Action {action_len} too big :("); } - let mut action_buf = vec![0; action_len as usize]; - sock.read_exact(&mut action_buf).await.unwrap(); - - let command = FileServerMessage::from_bytes(&action_buf).unwrap(); - std::mem::drop(action_buf); + let command = { + let mut action_buf = vec![0; action_len as usize]; + sock.read_exact(&mut action_buf).await.unwrap(); + FileServerMessage::from_bytes(&action_buf).unwrap() + }; let authentication = command.auth.unwrap(); let macaroon = Macaroon::deserialize(&authentication.macaroon).unwrap(); @@ -172,25 +172,25 @@ pub async fn handle_download_chunk( chunk_id: ChunkID, ) -> Result)>> { let caveats = macaroon.first_party_caveats(); - - let username_caveat = caveats + let email = caveats .iter() .find_map(|caveat| { let Caveat::FirstParty(caveat) = caveat else { return None; }; - let username_caveat: UsernameCaveat = match caveat.predicate().try_into() { + + let email_caveat: EmailCaveat = match caveat.predicate().try_into() { Ok(caveat) => caveat, Err(_) => return None, }; - Some(username_caveat) + Some(email_caveat.email) }) .unwrap(); let mut verifier = Verifier::default(); - verifier.satisfy_exact(username_caveat.clone().into()); + verifier.satisfy_exact(format!("email = {email}").into()); verifier.satisfy_general(check_token_valid); verifier @@ -199,10 +199,7 @@ pub async fn handle_download_chunk( let path = format!("chunks/{}", chunk_id); - let chunk_meta = if let Some(chunk_meta) = chunk_db - .get_chunk_meta(chunk_id, username_caveat.username.as_str()) - .await? - { + let chunk_meta = if let Some(chunk_meta) = chunk_db.get_chunk_meta(chunk_id, &email).await? { chunk_meta } else { return Ok(None); @@ -232,33 +229,33 @@ async fn query_chunks_uploaded( ) -> Result> { let caveats = macaroon.first_party_caveats(); - let username_caveat = caveats + let email_caveat = caveats .iter() .find_map(|caveat| { let Caveat::FirstParty(caveat) = caveat else { return None; }; - let username_caveat: UsernameCaveat = match caveat.predicate().try_into() { + let email_caveat: EmailCaveat = match caveat.predicate().try_into() { Ok(caveat) => caveat, Err(_) => return None, }; - Some(username_caveat) + Some(email_caveat) }) .unwrap(); let mut verifier = Verifier::default(); - verifier.satisfy_exact(username_caveat.clone().into()); + verifier.satisfy_exact(email_caveat.clone().into()); verifier .verify(&macaroon, macaroon_key, Vec::new()) .map_err(|_| AuthErr)?; - let username = &username_caveat.username; + let email = &email_caveat.email; let chunks_uploaded: HashMap = futures::future::join_all(chunks.into_iter().map(|chunk_id| async move { - let contains_chunk: bool = chunk_db.contains_chunk(chunk_id, username).await.unwrap(); + let contains_chunk: bool = chunk_db.contains_chunk(chunk_id, email).await.unwrap(); (chunk_id, contains_chunk) })) .await @@ -278,31 +275,36 @@ async fn handle_upload_chunk( trace!("Handling chunk upload"); let caveats = macaroon.first_party_caveats(); - trace!("Caveats: {caveats:?}"); - // TODO: swap this to satisfy_general - let username_caveat = caveats + let email = caveats .iter() .find_map(|caveat| { let Caveat::FirstParty(caveat) = caveat else { return None; }; - let username_caveat: UsernameCaveat = match caveat.predicate().try_into() { + + let email_caveat: EmailCaveat = match caveat.predicate().try_into() { Ok(caveat) => caveat, Err(_) => return None, }; - Some(username_caveat) + Some(email_caveat.email) }) .unwrap(); let mut verifier = Verifier::default(); verifier.satisfy_general(check_token_valid); - verifier.satisfy_exact(username_caveat.clone().into()); + //FIXME: + /* + verifier.satisfy_exact(format!("email = {email}").into()); verifier .verify(&macaroon, macaroon_key, Vec::new()) - .map_err(|_| AuthErr)?; + .map_err(|err| { + debug!("Error verifying macaroon: {err}"); + AuthErr + })?; + */ trace!("Verified caveats"); @@ -326,9 +328,7 @@ async fn handle_upload_chunk( chunk_file.write_all(chunk).await?; trace!("Wrote chunk file"); - chunk_db - .insert_chunk(chunk_metadata, &username_caveat.username) - .await?; + chunk_db.insert_chunk(chunk_metadata, &email).await?; trace!("Inserting chunk into db"); info!("Uploaded chunk {chunk_id}");