From daa4ad137c405b45955b2122d336ae303631222c Mon Sep 17 00:00:00 2001 From: Martin Indra Date: Tue, 29 Nov 2022 17:56:12 +0100 Subject: [PATCH] Kick off lobby server Relates to #255. --- CONTRIBUTING.md | 2 + Cargo.lock | 1125 ++++++++++++++++++++++++++- crates/server/Cargo.toml | 25 + crates/server/README.md | 13 + crates/server/src/auth/db.rs | 126 +++ crates/server/src/auth/endpoints.rs | 72 ++ crates/server/src/auth/mod.rs | 58 ++ crates/server/src/auth/passwd.rs | 59 ++ crates/server/src/auth/token.rs | 73 ++ crates/server/src/main.rs | 43 + 10 files changed, 1574 insertions(+), 22 deletions(-) create mode 100644 crates/server/Cargo.toml create mode 100644 crates/server/README.md create mode 100644 crates/server/src/auth/db.rs create mode 100644 crates/server/src/auth/endpoints.rs create mode 100644 crates/server/src/auth/mod.rs create mode 100644 crates/server/src/auth/passwd.rs create mode 100644 crates/server/src/auth/token.rs create mode 100644 crates/server/src/main.rs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd228eefb..512e8bd77 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,6 +89,8 @@ The intention is: Topologically sorted crates: +* [de_server](/crates/server) – lobby server. + * [de_uom](/crates/uom) – type safe units of measurements. * [core](/crates/core) – various simple core utilities, structs, and so on. diff --git a/Cargo.lock b/Cargo.lock index a509c2f9e..14646def7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,185 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330223a1aecc308757b9926e9391c9b47f8ef2dbd8aea9df88312aea18c5e8d6" +[[package]] +name = "actix-codec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "log", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "actix-http" +version = "3.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64 0.13.1", + "bitflags", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1 0.10.5", + "smallvec", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +dependencies = [ + "bytestring", + "http", + "regex", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "num_cpus", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "adler" version = "1.0.2" @@ -50,6 +229,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "alsa" version = "0.6.0" @@ -281,6 +475,15 @@ version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-polyfill" version = "0.1.11" @@ -331,6 +534,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64ct" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" + [[package]] name = "bevy" version = "0.9.1" @@ -393,7 +602,7 @@ dependencies = [ "js-sys", "ndk-glue", "notify", - "parking_lot", + "parking_lot 0.12.1", "serde", "thiserror", "wasm-bindgen", @@ -413,7 +622,7 @@ dependencies = [ "bevy_ecs", "bevy_reflect", "bevy_utils", - "parking_lot", + "parking_lot 0.12.1", "rodio", ] @@ -716,7 +925,7 @@ dependencies = [ "erased-serde", "glam", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "serde", "smallvec", "thiserror", @@ -769,7 +978,7 @@ dependencies = [ "image 0.24.5", "naga", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "regex", "serde", "smallvec", @@ -1026,6 +1235,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + [[package]] name = "blocking" version = "1.3.0" @@ -1040,6 +1258,27 @@ dependencies = [ "futures-lite", ] +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.11.1" @@ -1078,6 +1317,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +[[package]] +name = "bytestring" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7f83e57d9154148e355404702e2694463241880b939570d7c97c014da7a69a1" +dependencies = [ + "bytes", +] + [[package]] name = "cache-padded" version = "1.2.0" @@ -1313,6 +1561,23 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -1390,7 +1655,7 @@ dependencies = [ "ndk-context", "oboe", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "stdweb", "thiserror", "wasm-bindgen", @@ -1398,6 +1663,30 @@ dependencies = [ "windows 0.37.0", ] +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" + [[package]] name = "crc32fast" version = "1.3.2" @@ -1483,6 +1772,16 @@ dependencies = [ "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.14" @@ -1492,6 +1791,16 @@ 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", + "typenum", +] + [[package]] name = "ctor" version = "0.1.26" @@ -1773,6 +2082,23 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "de_server" +version = "0.1.0-dev" +dependencies = [ + "actix-web", + "anyhow", + "base64 0.13.1", + "futures-util", + "jsonwebtoken", + "mime", + "pbkdf2", + "rand_core", + "serde", + "sqlx", + "thiserror", +] + [[package]] name = "de_signs" version = "0.1.0-dev" @@ -1854,6 +2180,30 @@ dependencies = [ "byteorder", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + [[package]] name = "discard" version = "1.0.4" @@ -1866,6 +2216,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dotenvy" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" + [[package]] name = "downcast-rs" version = "1.2.0" @@ -1910,6 +2266,15 @@ dependencies = [ "syn", ] +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + [[package]] name = "enum-map" version = "2.4.1" @@ -2022,6 +2387,18 @@ dependencies = [ "miniz_oxide 0.6.2", ] +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.4", +] + [[package]] name = "fnv" version = "1.0.7" @@ -2043,6 +2420,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -2059,6 +2445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -2067,6 +2454,28 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + [[package]] name = "futures-io" version = "0.3.25" @@ -2089,17 +2498,65 @@ dependencies = [ ] [[package]] -name = "fxhash" -version = "0.2.1" +name = "futures-macro" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ - "byteorder", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "getrandom" -version = "0.2.8" +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ @@ -2135,7 +2592,7 @@ dependencies = [ "libc", "libudev-sys", "log", - "nix 0.25.0", + "nix 0.25.1", "uuid", "vec_map", "wasm-bindgen", @@ -2280,6 +2737,25 @@ dependencies = [ "svg_fmt", ] +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "1.8.2" @@ -2316,6 +2792,15 @@ dependencies = [ "serde", ] +[[package]] +name = "hashlink" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +dependencies = [ + "hashbrown", +] + [[package]] name = "heapless" version = "0.7.16" @@ -2325,7 +2810,7 @@ dependencies = [ "atomic-polyfill", "hash32", "rustc_version 0.4.0", - "spin", + "spin 0.9.4", "stable_deref_trait", ] @@ -2334,6 +2819,9 @@ name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -2375,12 +2863,54 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "image" version = "0.23.14" @@ -2574,6 +3104,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa4b4af834c6cfd35d8763d359661b90f2e45d8f750a0849156c7f4671af09c" +dependencies = [ + "base64 0.13.1", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + [[package]] name = "khronos-egl" version = "4.1.0" @@ -2614,6 +3158,12 @@ dependencies = [ "log", ] +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "lazy_static" version = "1.4.0" @@ -2659,6 +3209,17 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libudev-sys" version = "0.1.4" @@ -2675,6 +3236,24 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +[[package]] +name = "local-channel" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + [[package]] name = "lock_api" version = "0.4.9" @@ -2769,6 +3348,12 @@ dependencies = [ "objc", ] +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2902,7 +3487,7 @@ dependencies = [ "ndk-macro", "ndk-sys 0.4.1+23.1.7779620", "once_cell", - "parking_lot", + "parking_lot 0.12.1", ] [[package]] @@ -2951,9 +3536,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", "bitflags", @@ -3032,6 +3617,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.2" @@ -3232,6 +3828,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" +[[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.5", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -3239,7 +3846,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.5", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", ] [[package]] @@ -3297,18 +3918,50 @@ dependencies = [ "spade", ] +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + [[package]] name = "paste" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pem" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "percent-encoding" version = "2.2.0" @@ -3438,6 +4091,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.2.1" @@ -3503,6 +4162,36 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b" +[[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 = "range-alloc" version = "0.1.2" @@ -3612,6 +4301,21 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "robust" version = "0.2.3" @@ -3687,6 +4391,27 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "rustls" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "ryu" version = "1.0.11" @@ -3723,6 +4448,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "semver" version = "0.9.0" @@ -3775,6 +4510,18 @@ dependencies = [ "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.6.1" @@ -3784,12 +4531,34 @@ dependencies = [ "sha1_smol", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha1_smol" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -3837,6 +4606,18 @@ dependencies = [ "wide", ] +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + [[package]] name = "slab" version = "0.4.7" @@ -3886,6 +4667,12 @@ dependencies = [ "smallvec", ] +[[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.4" @@ -3905,6 +4692,103 @@ dependencies = [ "num-traits", ] +[[package]] +name = "sqlformat" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" +dependencies = [ + "ahash", + "atoi", + "bitflags", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls", + "rustls-pemfile", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3956,7 +4840,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha1", + "sha1 0.6.1", "syn", ] @@ -3966,12 +4850,28 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "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.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "svg_fmt" version = "0.4.1" @@ -4060,6 +4960,33 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -4085,6 +5012,61 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokio" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "winapi", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml" version = "0.5.9" @@ -4101,6 +5083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4179,12 +5162,33 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + [[package]] name = "unicode-ident" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" + [[package]] name = "unicode-width" version = "0.1.10" @@ -4197,6 +5201,29 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "uuid" version = "1.2.2" @@ -4223,6 +5250,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -4334,6 +5367,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" +dependencies = [ + "webpki", +] + [[package]] name = "wepoll-ffi" version = "0.1.2" @@ -4353,7 +5405,7 @@ dependencies = [ "js-sys", "log", "naga", - "parking_lot", + "parking_lot 0.12.1", "raw-window-handle 0.5.0", "smallvec", "static_assertions", @@ -4379,7 +5431,7 @@ dependencies = [ "fxhash", "log", "naga", - "parking_lot", + "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.0", "smallvec", @@ -4415,7 +5467,7 @@ dependencies = [ "metal", "naga", "objc", - "parking_lot", + "parking_lot 0.12.1", "profiling", "range-alloc", "raw-window-handle 0.5.0", @@ -4655,7 +5707,7 @@ dependencies = [ "ndk-glue", "objc", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "percent-encoding", "raw-window-handle 0.4.3", "raw-window-handle 0.5.0", @@ -4690,3 +5742,32 @@ name = "xi-unicode" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.4+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa202f2ef00074143e219d15b62ffc317d17cc33909feac471c044087cad7b0" +dependencies = [ + "cc", + "libc", +] diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml new file mode 100644 index 000000000..f257da564 --- /dev/null +++ b/crates/server/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "de_server" +description = "Digital Extinction lobby server." + +version.workspace = true +edition.workspace = true +authors.workspace = true +repository.workspace = true +keywords.workspace = true +homepage.workspace = true +license.workspace = true +categories.workspace = true + +[dependencies] +actix-web = "4.2.1" +anyhow = "1.0.66" +base64 = "0.13.1" +futures-util = "0.3" +jsonwebtoken = "8.1.1" +mime = "0.3.16" +pbkdf2 = { version = "0.11.0", features = ["std"] } +rand_core = { version = "0.6", features = ["std"] } +serde = { version = "1.0", features = ["derive"] } +sqlx = { version = "0.6.2", features = [ "runtime-actix-rustls" , "sqlite" ] } +thiserror = "1.0" diff --git a/crates/server/README.md b/crates/server/README.md new file mode 100644 index 000000000..ec2d020fc --- /dev/null +++ b/crates/server/README.md @@ -0,0 +1,13 @@ +# Digital Extinction Server + +TODO explain +TODO link to API docs + +## Configuration + +The server is configured via environment variables. + +* `DE_SERVER_JWT_SECRET` – A Base64 encoded secret used for signing and + validating of JSON Web Tokens. TODO length? +* `DE_SERVER_DB_URL` – SQLite database URL passed to `SqliteConnectOptions` of + `sqlx` Rust library. diff --git a/crates/server/src/auth/db.rs b/crates/server/src/auth/db.rs new file mode 100644 index 000000000..575527605 --- /dev/null +++ b/crates/server/src/auth/db.rs @@ -0,0 +1,126 @@ +use std::sync::Arc; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use sqlx::{query, sqlite::SqliteRow, Pool, Row, Sqlite}; +use thiserror::Error; + +use super::passwd::DbPassword; + +const INIT_QUERY: &str = r#" +CREATE TABLE IF NOT EXISTS users ( + username CHARACTER(64) NOT NULL PRIMARY KEY, + pass_hash CHARACTER(32) NOT NULL, + pass_salt CHARACTER(64) NOT NULL +); +"#; + +#[derive(Clone)] +pub struct Users { + pool: Arc>, +} + +impl Users { + pub async fn init(pool: Arc>) -> Result { + query(INIT_QUERY).execute(pool.as_ref()).await?; + Ok(Self { pool }) + } + + pub async fn register(&self, user: &UserWithPassword) -> Result<(), RegistrationError> { + let password = + DbPassword::generate(user.password()).map_err(|e| RegistrationError::Other(e))?; + + let result = query("INSERT INTO users (username, pass_hash, pass_salt) VALUES(?, ?, ?);") + .bind(user.user().username()) + .bind(password.hashed()) + .bind(password.salt_str()) + .execute(self.pool.as_ref()) + .await; + + if let Err(sqlx::Error::Database(ref error)) = result { + if let Some(code) = error.code() { + if code == "1555" { + return Err(RegistrationError::UsernameTaken); + } + } + } + + result.map_err(|e| RegistrationError::Database(e))?; + Ok(()) + } + + pub async fn login(&self, user: &UsernameAndPassword) -> Result { + let row = query("SELECT pass_hash, pass_salt FROM users WHERE username = ?;") + .bind(user.username()) + .fetch_optional(self.pool.as_ref()) + .await?; + let Some(row) = row else { return Ok(false) }; + Ok(DbPassword::try_from(row)?.check(user.password())) + } +} + +#[derive(Error, Debug)] +pub enum RegistrationError { + #[error("Username is already taken")] + UsernameTaken, + #[error("A database error encountered")] + Database(#[source] sqlx::Error), + #[error(transparent)] + Other(#[from] anyhow::Error), +} + +// TODO move to model +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct UsernameAndPassword { + username: String, + password: String, +} + +impl UsernameAndPassword { + pub fn username(&self) -> &str { + self.username.as_str() + } + + fn password(&self) -> &str { + self.password.as_str() + } +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct UserWithPassword { + password: String, + user: User, +} + +impl UserWithPassword { + pub fn user(&self) -> &User { + &self.user + } + + fn password(&self) -> &str { + self.password.as_str() + } +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct User { + username: String, +} + +impl User { + pub fn username(&self) -> &str { + self.username.as_str() + } +} + +impl TryFrom for User { + type Error = anyhow::Error; + + fn try_from(row: SqliteRow) -> Result { + let username: String = row.try_get("username")?; + Ok(Self { username }) + } +} diff --git a/crates/server/src/auth/endpoints.rs b/crates/server/src/auth/endpoints.rs new file mode 100644 index 000000000..d1dc24c03 --- /dev/null +++ b/crates/server/src/auth/endpoints.rs @@ -0,0 +1,72 @@ +use actix_web::{post, web, HttpResponse, Responder}; +use serde::Serialize; + +use super::db::RegistrationError; +use crate::auth::{ + db::{UserWithPassword, UsernameAndPassword, Users}, + token::{Claims, Tokens}, +}; + +// TODO docs +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service(web::scope("/p/auth").service(sign_up).service(sign_in)); +} + +#[derive(Serialize)] +struct TokenResponse { + token: String, +} + +#[post("/sign-up")] +async fn sign_up( + tokens: web::Data, + users: web::Data, + user: web::Json, +) -> impl Responder { + // TODO validate 1 <= name.len() <= CONSTANT + // TODO validate 1 <= password.len() <= CONSTANT + + let token = match tokens.encode(&Claims::standard(user.0.user().username())) { + Ok(token) => token, + Err(error) => { + // TODO log the error + println!("{:?}", error); + return HttpResponse::InternalServerError().finish(); + } + }; + + match users.register(&user.0).await { + Ok(_) => HttpResponse::Ok().json(TokenResponse { token }), + Err(RegistrationError::UsernameTaken) => { + HttpResponse::Conflict().json("The username is already taken") + } + Err(error) => { + // TODO proper logging + println!("{:?}", error); + HttpResponse::InternalServerError().finish() + } + } +} + +#[post("/sign-in")] +async fn sign_in( + tokens: web::Data, + users: web::Data, + user: web::Json, +) -> impl Responder { + match users.login(&user.0).await { + Ok(false) => HttpResponse::Unauthorized().finish(), + Ok(true) => { + let token = match tokens.encode(&Claims::standard(user.0.username())) { + Ok(token) => token, + Err(error) => { + // TODO log the error + return HttpResponse::InternalServerError().finish(); + } + }; + HttpResponse::Ok().json(TokenResponse { token }) + } + // TODO log the error + Err(error) => HttpResponse::InternalServerError().finish(), + } +} diff --git a/crates/server/src/auth/mod.rs b/crates/server/src/auth/mod.rs new file mode 100644 index 000000000..3592ba4ad --- /dev/null +++ b/crates/server/src/auth/mod.rs @@ -0,0 +1,58 @@ +use std::{env, sync::Arc}; + +use actix_web::web; +use anyhow::{bail, Context, Result}; +use sqlx::{Pool, Sqlite}; + +use self::{db::Users, token::Tokens}; + +mod db; +mod endpoints; +mod passwd; +mod token; + +const JWT_SECRET_VAR_NAME: &str = "DE_JWT_SECRET"; +const MIN_SECRET_LEN: usize = 12; +const MAX_SECRET_LEN: usize = 86; + +// TODO doc +#[derive(Clone)] +pub struct Auth { + tokens: Tokens, + users: Users, +} + +impl Auth { + pub async fn new(pool: Arc>) -> Result { + let jwt_secret = env::var(JWT_SECRET_VAR_NAME).context(format!( + "Failed to read environment variable {}", + JWT_SECRET_VAR_NAME + ))?; + + if jwt_secret.len() < MIN_SECRET_LEN { + bail!( + "JWT secret is too short: {} < {}", + jwt_secret.len(), + MIN_SECRET_LEN + ); + } + if jwt_secret.len() > MAX_SECRET_LEN { + bail!( + "JWT secret is too long: {} > {}", + jwt_secret.len(), + MAX_SECRET_LEN + ); + } + + Ok(Self { + tokens: Tokens::new(jwt_secret.as_str())?, + users: Users::init(pool).await?, + }) + } + + pub fn configure(&self, cfg: &mut web::ServiceConfig) { + cfg.app_data(web::Data::new(self.tokens.clone())); + cfg.app_data(web::Data::new(self.users.clone())); + endpoints::configure(cfg); + } +} diff --git a/crates/server/src/auth/passwd.rs b/crates/server/src/auth/passwd.rs new file mode 100644 index 000000000..36baa3b22 --- /dev/null +++ b/crates/server/src/auth/passwd.rs @@ -0,0 +1,59 @@ +use anyhow::{Context, Error, Result}; +use pbkdf2::{ + password_hash::{PasswordHasher, SaltString}, + Pbkdf2, +}; +use rand_core::OsRng; +use sqlx::{sqlite::SqliteRow, Row}; + +pub struct DbPassword(String, SaltString); + +// TODO docs +impl DbPassword { + pub fn generate(password: &str) -> Result { + let salt = SaltString::generate(&mut OsRng); + let hashed = Self::hash(password, &salt)?; + Ok(Self::new(hashed, salt)) + } + + fn new(hashed: String, salt: SaltString) -> Self { + Self(hashed, salt) + } + + fn hash(password: &str, salt: &SaltString) -> Result { + Ok(Pbkdf2 + .hash_password(password.as_bytes(), salt) + .context("Failed to hash the password")? + .to_string()) + } + + pub fn hashed(&self) -> &str { + self.0.as_str() + } + + pub fn salt_str(&self) -> &str { + self.1.as_str() + } + + pub fn check(&self, password: &str) -> bool { + let Ok(hashed) = Self::hash(password, &self.1) else { return false }; + // TODO constant time comparison + self.0 == hashed + } +} + +impl TryFrom for DbPassword { + type Error = Error; + + fn try_from(row: SqliteRow) -> Result { + let hashed: String = row + .try_get("pass_hash") + .context("Failed to retrieve password hash from the DB")?; + let salt: String = row + .try_get("pass_salt") + .context("Failed to retrieve password salt from the DB")?; + let salt = + SaltString::new(salt.as_str()).context("Invalid password salt loaded from the DB")?; + Ok(Self::new(hashed, salt)) + } +} diff --git a/crates/server/src/auth/token.rs b/crates/server/src/auth/token.rs new file mode 100644 index 000000000..a49d60250 --- /dev/null +++ b/crates/server/src/auth/token.rs @@ -0,0 +1,73 @@ +use anyhow::{Context, Result}; +use jsonwebtoken::{ + decode, encode, get_current_timestamp, DecodingKey, EncodingKey, Header, Validation, +}; +use serde::{Deserialize, Serialize}; + +const TOKEN_LIFETIME: u64 = 86400; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + sub: String, + exp: u64, +} + +impl Claims { + /// Creates and returns new claims for a particular user. The expiration is + /// set to now + a fixed offset. + pub fn standard>(user: U) -> Self { + Self { + sub: user.into(), + exp: get_current_timestamp() + TOKEN_LIFETIME, + } + } + + /// Returns subject user ID (`sub` property of the JWT). + pub fn user(&self) -> &str { + self.sub.as_str() + } +} + +#[derive(Clone)] +pub struct Tokens { + encoding_key: EncodingKey, + decoding_key: DecodingKey, +} + +impl Tokens { + pub fn new(secret: &str) -> Result { + let secret = base64::decode(secret).context("Failed to decode JWT secret")?; + let encoding_key = EncodingKey::from_secret(secret.as_ref()); + let decoding_key = DecodingKey::from_secret(secret.as_ref()); + Ok(Self { + encoding_key, + decoding_key, + }) + } + + /// Encodes a user ID into a new JWT. + pub fn encode(&self, claims: &Claims) -> Result { + encode(&Header::default(), &claims, &self.encoding_key).context("Failed to encode JWT") + } + + /// Decodes and validates a JWT. + pub fn decode(&self, token: &str) -> Result { + decode(token, &self.decoding_key, &Validation::default()) + .context("Failed to decode JWT") + .map(|t| t.claims) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_tokens() { + let secret_base64 = "eHg="; + let tokens = Tokens::new(secret_base64).unwrap(); + let token = tokens.encode(&Claims::standard("Indy")).unwrap(); + let claims = tokens.decode(&token).unwrap(); + assert_eq!(claims.user(), "Indy"); + } +} diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs new file mode 100644 index 000000000..97a2a78be --- /dev/null +++ b/crates/server/src/main.rs @@ -0,0 +1,43 @@ +use std::{env, sync::Arc}; + +use actix_web::{web, App, HttpServer}; +use anyhow::{Context, Result}; +use auth::Auth; +use sqlx::{sqlite::SqlitePoolOptions, Pool, Sqlite}; + +mod auth; + +const JSON_PAYLOAD_LIMIT: usize = 10 * 1024; +const DB_URL_VAR_NAME: &str = "DE_DB_URL"; + +#[actix_web::main] +async fn main() -> std::io::Result<()> { + let json_cfg = web::JsonConfig::default() + .limit(JSON_PAYLOAD_LIMIT) + .content_type(|mime| mime == mime::APPLICATION_JSON) + .content_type_required(true); + + // TODO do not unwrap + let db_pool = db_pool().await.unwrap(); + // TODO do not unwrap + let auth = Auth::new(db_pool).await.unwrap(); + + HttpServer::new(move || { + App::new() + .app_data(json_cfg.clone()) + .configure(|c| auth.configure(c)) + }) + .bind(("0.0.0.0", 8080))? + .run() + .await +} + +async fn db_pool() -> Result>> { + let db_url = env::var(DB_URL_VAR_NAME).context(format!( + "Failed to read environment variable {}", + DB_URL_VAR_NAME + ))?; + Ok(Arc::new( + SqlitePoolOptions::new().connect(db_url.as_str()).await?, + )) +}