diff --git a/Cargo.lock b/Cargo.lock index a072344..d1063f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,47 +2,199 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" + +[[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.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash 0.8.3", + "base64 0.21.0", + "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", + "smallvec", + "tokio", + "tokio-util", + "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 1.0.107", +] + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" +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.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash 0.7.6", + "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 0.3.17", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2262160a7ae29e3415554a3f1fc04c764b1540c116aa524683208078b7a75bc9" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn 1.0.107", +] + [[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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "ahash" version = "0.7.6" @@ -54,6 +206,48 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom 0.2.8", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + +[[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 = "android_system_properties" version = "0.1.5" @@ -64,20 +258,27 @@ dependencies = [ ] [[package]] -name = "async-stream" -version = "0.3.3" +name = "arrayvec" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-stream" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e" dependencies = [ "async-stream-impl", "futures-core", + "pin-project-lite", ] [[package]] name = "async-stream-impl" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" dependencies = [ "proc-macro2", "quote", @@ -104,15 +305,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg", -] - [[package]] name = "atty" version = "0.2.14" @@ -131,10 +323,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "base32" -version = "0.4.0" +name = "bae" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "33b8de67cc41132507eeece2584804efcb15f85ba516e34c944b7667f480397a" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.107", +] [[package]] name = "base64" @@ -142,12 +341,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" - [[package]] name = "base64" version = "0.21.0" @@ -171,10 +364,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] -name = "binascii" -version = "0.1.4" +name = "bigdecimal" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] [[package]] name = "bitflags" @@ -191,6 +389,72 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive", + "hashbrown", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate", + "proc-macro2", + "syn 1.0.107", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -198,10 +462,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] -name = "bytemuck" -version = "1.13.0" +name = "bytecheck" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] [[package]] name = "byteorder" @@ -215,11 +495,23 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "bytestring" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +dependencies = [ + "bytes", +] + [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -237,21 +529,12 @@ dependencies = [ "js-sys", "num-integer", "num-traits", + "serde", "time 0.1.45", "wasm-bindgen", "winapi", ] -[[package]] -name = "cipher" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clap" version = "4.1.10" @@ -273,7 +556,7 @@ version = "4.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fddf67631444a3a3e3e5ac51c36a5e01335302de677bd78759eaa90ab1f46644" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -299,12 +582,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colored" version = "2.0.0" @@ -323,10 +600,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] -name = "constant_time_eq" -version = "0.2.4" +name = "convert_case" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cookie" @@ -334,14 +611,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ - "aes-gcm", - "base64 0.20.0", - "hkdf", - "hmac", "percent-encoding", - "rand", - "sha2", - "subtle", "time 0.3.17", "version_check", ] @@ -371,21 +641,6 @@ 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.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - [[package]] name = "crc32fast" version = "1.3.2" @@ -407,9 +662,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -421,19 +676,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - [[package]] name = "ctrlc" version = "3.2.5" @@ -528,35 +773,15 @@ dependencies = [ ] [[package]] -name = "devise" -version = "0.3.1" +name = "derive_more" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "devise_codegen", - "devise_core", -] - -[[package]] -name = "devise_codegen" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" -dependencies = [ - "devise_core", - "quote", -] - -[[package]] -name = "devise_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" -dependencies = [ - "bitflags", + "convert_case", "proc-macro2", - "proc-macro2-diagnostics", "quote", + "rustc_version", "syn 1.0.107", ] @@ -639,9 +864,9 @@ dependencies = [ [[package]] name = "dotenvy" -version = "0.15.6" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "ed25519" @@ -726,20 +951,6 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" -[[package]] -name = "figment" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" -dependencies = [ - "atomic", - "pear", - "serde", - "toml 0.5.11", - "uncased", - "version_check", -] - [[package]] name = "filetime" version = "0.2.20" @@ -868,19 +1079,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generator" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266041a359dfa931b370ef684cceb84b166beb14f7f0421f4a6a3d0c446d12e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows", -] - [[package]] name = "generic-array" version = "0.14.6" @@ -913,22 +1111,6 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "ghash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "h2" version = "0.3.15" @@ -954,7 +1136,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.6", ] [[package]] @@ -966,6 +1148,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "heck" version = "0.4.1" @@ -1128,20 +1319,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "image" -version = "0.24.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "num-rational", - "num-traits", - "png", -] - [[package]] name = "indexmap" version = "1.9.2" @@ -1150,22 +1327,6 @@ checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", - "serde", -] - -[[package]] -name = "inlinable_string" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", ] [[package]] @@ -1224,6 +1385,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.61" @@ -1233,6 +1403,12 @@ dependencies = [ "wasm-bindgen", ] +[[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" @@ -1266,6 +1442,24 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[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" @@ -1285,30 +1479,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - [[package]] name = "md-5" version = "0.10.5" @@ -1357,26 +1527,6 @@ dependencies = [ "windows-sys 0.42.0", ] -[[package]] -name = "multer" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed4198ce7a4cbd2a57af78d28c6fbb57d81ac5f1d6ad79ac6c5587419cbdf22" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "memchr", - "mime", - "spin", - "tokio", - "tokio-util", - "version_check", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -1418,13 +1568,14 @@ dependencies = [ ] [[package]] -name = "nu-ansi-term" -version = "0.46.0" +name = "num-bigint" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ - "overload", - "winapi", + "autocfg", + "num-integer", + "num-traits", ] [[package]] @@ -1437,17 +1588,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1482,12 +1622,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openssl" version = "0.10.45" @@ -1550,10 +1684,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] -name = "overload" -version = "0.1.1" +name = "ouroboros" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" +dependencies = [ + "aliasable", + "ouroboros_macro", +] + +[[package]] +name = "ouroboros_macro" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" +dependencies = [ + "Inflector", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.107", +] [[package]] name = "packed_simd_2" @@ -1619,29 +1770,6 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" -[[package]] -name = "pear" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 1.0.107", -] - [[package]] name = "pem" version = "1.1.1" @@ -1691,36 +1819,21 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" -[[package]] -name = "png" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" -dependencies = [ - "bitflags", - "crc32fast", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polyval" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" -dependencies = [ - "cfg-if", - "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 = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml 0.5.11", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1755,24 +1868,25 @@ dependencies = [ ] [[package]] -name = "proc-macro2-diagnostics" -version = "0.9.1" +name = "ptr_meta" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" +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.107", - "version_check", - "yansi", ] -[[package]] -name = "qrcodegen" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" - [[package]] name = "quick-protobuf" version = "0.8.1" @@ -1850,41 +1964,14 @@ dependencies = [ "thiserror", ] -[[package]] -name = "ref-cast" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c78fb8c9293bcd48ef6fce7b4ca950ceaf21210de6e105a883ee280c0f7b9ed" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - [[package]] name = "regex" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] @@ -1894,6 +1981,15 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.11.16" @@ -1932,85 +2028,70 @@ dependencies = [ ] [[package]] -name = "rocket" -version = "0.5.0-rc.2" +name = "ring" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ead083fce4a405feb349cf09abdf64471c6077f14e0ce59364aa90d4b99317" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ - "async-stream", - "async-trait", - "atomic", - "atty", - "binascii", - "bytes", - "either", - "figment", - "futures", - "indexmap", - "log", - "memchr", - "multer", - "num_cpus", - "parking_lot 0.12.1", - "pin-project-lite", - "rand", - "ref-cast", - "rocket_codegen", - "rocket_http", - "serde", - "serde_json", - "state", - "tempfile", - "time 0.3.17", - "tokio", - "tokio-stream", - "tokio-util", - "ubyte", - "version_check", - "yansi", + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", ] [[package]] -name = "rocket_codegen" -version = "0.5.0-rc.2" +name = "rkyv" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6aeb6bb9c61e9cd2c00d70ea267bf36f76a4cc615e5908b349c2f9d93999b47" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" +dependencies = [ + "bytecheck", + "hashbrown", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" dependencies = [ - "devise", - "glob", - "indexmap", "proc-macro2", "quote", - "rocket_http", "syn 1.0.107", - "unicode-xid", ] [[package]] -name = "rocket_http" -version = "0.5.0-rc.2" +name = "rust_decimal" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ded65d127954de3c12471630bf4b81a2792f065984461e65b91d0fdaafc17a2" +checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc" dependencies = [ - "cookie", - "either", - "futures", - "http", - "hyper", - "indexmap", - "log", - "memchr", - "pear", - "percent-encoding", - "pin-project-lite", - "ref-cast", + "arrayvec", + "borsh", + "bytecheck", + "byteorder", + "bytes", + "num-traits", + "rand", + "rkyv", "serde", - "smallvec", - "stable-pattern", - "state", - "time 0.3.17", - "tokio", - "uncased", + "serde_json", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", ] [[package]] @@ -2028,10 +2109,31 @@ dependencies = [ ] [[package]] -name = "rustversion" -version = "1.0.11" +name = "rustls" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64 0.21.0", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "ryu" @@ -2048,12 +2150,6 @@ dependencies = [ "windows-sys 0.42.0", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.1.0" @@ -2066,6 +2162,129 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sea-orm" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d875e2fcd965320e50066028ac0b4877ff07edbb734a6ddfeff48a87dbab38" +dependencies = [ + "async-stream", + "async-trait", + "bigdecimal", + "chrono", + "futures", + "log", + "ouroboros", + "rust_decimal", + "sea-orm-macros", + "sea-query", + "sea-query-binder", + "sea-strum", + "serde", + "serde_json", + "sqlx", + "thiserror", + "time 0.3.17", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sea-orm-macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9b593e9c0cdbb18cafd4da7b92e67a9c2d9892934f3a2d8bbac73d5ba4a98a1" +dependencies = [ + "bae", + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "sea-query" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fbe015dbdaa7d8829d71c1e14fb6289e928ac256b93dfda543c85cd89d6f03" +dependencies = [ + "bigdecimal", + "chrono", + "rust_decimal", + "sea-query-derive", + "serde_json", + "time 0.3.17", + "uuid", +] + +[[package]] +name = "sea-query-binder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03548c63aec07afd4fd190923e0160d2f2fc92def27470b54154cf232da6203b" +dependencies = [ + "bigdecimal", + "chrono", + "rust_decimal", + "sea-query", + "serde_json", + "sqlx", + "time 0.3.17", + "uuid", +] + +[[package]] +name = "sea-query-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63f62030c60f3a691f5fe251713b4e220b306e50a71e1d6f9cce1f24bb781978" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.107", + "thiserror", +] + +[[package]] +name = "sea-strum" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391d06a6007842cfe79ac6f7f53911b76dfd69fc9a6769f1cf6569d12ce20e1b" +dependencies = [ + "sea-strum_macros", +] + +[[package]] +name = "sea-strum_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b4397b825df6ccf1e98bcdabef3bbcfc47ff5853983467850eeab878384f21" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.107", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "security-framework" version = "2.8.2" @@ -2089,6 +2308,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + [[package]] name = "serde" version = "1.0.159" @@ -2185,15 +2410,6 @@ dependencies = [ "digest 0.10.6", ] -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -2209,6 +2425,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "simple_logger" version = "4.1.0" @@ -2249,9 +2471,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" @@ -2286,17 +2508,18 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" +checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash", + "ahash 0.7.6", "atoi", "base64 0.13.1", + "bigdecimal", "bitflags", "byteorder", "bytes", - "crc", + "chrono", "crossbeam-queue", "dirs 4.0.0", "dotenvy", @@ -2316,10 +2539,14 @@ dependencies = [ "log", "md-5", "memchr", + "num-bigint", "once_cell", "paste", "percent-encoding", "rand", + "rust_decimal", + "rustls", + "rustls-pemfile", "serde", "serde_json", "sha1", @@ -2329,8 +2556,11 @@ dependencies = [ "sqlx-rt", "stringprep", "thiserror", + "time 0.3.17", "tokio-stream", "url", + "uuid", + "webpki-roots", "whoami", ] @@ -2342,11 +2572,11 @@ checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" dependencies = [ "dotenvy", "either", - "heck", + "heck 0.4.1", "once_cell", "proc-macro2", "quote", - "sha2", + "serde_json", "sqlx-core", "sqlx-rt", "syn 1.0.107", @@ -2355,32 +2585,13 @@ dependencies = [ [[package]] name = "sqlx-rt" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" +checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" dependencies = [ - "native-tls", "once_cell", "tokio", - "tokio-native-tls", -] - -[[package]] -name = "stable-pattern" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" -dependencies = [ - "memchr", -] - -[[package]] -name = "state" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" -dependencies = [ - "loom", + "tokio-rustls", ] [[package]] @@ -2480,7 +2691,7 @@ dependencies = [ [[package]] name = "tfclient" -version = "0.1.4" +version = "0.1.5" dependencies = [ "base64 0.21.0", "base64-serde", @@ -2527,15 +2738,6 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - [[package]] name = "time" version = "0.1.45" @@ -2607,21 +2809,9 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", - "tokio-macros", "windows-sys 0.42.0", ] -[[package]] -name = "tokio-macros" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - [[package]] name = "tokio-native-tls" version = "0.3.0" @@ -2633,10 +2823,21 @@ dependencies = [ ] [[package]] -name = "tokio-stream" -version = "0.1.11" +name = "tokio-rustls" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ "futures-core", "pin-project-lite", @@ -2700,25 +2901,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "totp-rs" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdd21080b6cf581e0c8fe849626ad627b42af1a0f71ce980244f2d6b1a47836" -dependencies = [ - "base32", - "base64 0.20.0", - "constant_time_eq", - "hmac", - "image", - "qrcodegen", - "rand", - "sha1", - "sha2", - "url", - "urlencoding", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -2732,6 +2914,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2755,62 +2938,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] name = "trifid-api" version = "0.1.0" dependencies = [ - "aes-gcm", - "base64 0.21.0", - "chrono", - "dotenvy", + "actix-web", "hex", - "ipnet", "log", - "paste", + "once_cell", "rand", - "rocket", + "sea-orm", "serde", - "sha2", - "sqlx", - "tokio", + "simple_logger", "toml 0.7.3", - "totp-rs", - "trifid-pki", - "url", - "urlencoding", - "uuid", ] [[package]] @@ -2841,25 +2983,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "ubyte" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" -dependencies = [ - "serde", -] - -[[package]] -name = "uncased" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" -dependencies = [ - "serde", - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.10" @@ -2905,22 +3028,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -[[package]] -name = "universal-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" -dependencies = [ - "crypto-common", - "subtle", -] - [[package]] name = "unsafe-libyaml" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad2024452afd3874bf539695e04af6732ba06517424dbf958fdb16a01f3bef6c" +[[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" @@ -2930,43 +3049,17 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] -[[package]] -name = "urlencoding" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" - [[package]] name = "uuid" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ - "getrandom 0.2.8", - "rand", - "uuid-macro-internal", + "serde", ] -[[package]] -name = "uuid-macro-internal" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b300a878652a387d2a0de915bdae8f1a548f0c6d45e072fe2688794b656cc9" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "vcpkg" version = "0.2.15" @@ -3084,10 +3177,29 @@ dependencies = [ ] [[package]] -name = "whoami" -version = "1.3.0" +name = "webpki" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45dbc71f0cdca27dc261a9bd37ddec174e4a0af2b900b890f378460f745426e3" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "whoami" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" dependencies = [ "wasm-bindgen", "web-sys", @@ -3124,19 +3236,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" -dependencies = [ - "windows_aarch64_msvc 0.39.0", - "windows_i686_gnu 0.39.0", - "windows_i686_msvc 0.39.0", - "windows_x86_64_gnu 0.39.0", - "windows_x86_64_msvc 0.39.0", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -3144,12 +3243,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", + "windows_x86_64_msvc", ] [[package]] @@ -3168,12 +3267,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", + "windows_x86_64_msvc", ] [[package]] @@ -3182,48 +3281,24 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" -[[package]] -name = "windows_aarch64_msvc" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" - [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" -[[package]] -name = "windows_i686_gnu" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" - [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" -[[package]] -name = "windows_i686_msvc" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" - [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" -[[package]] -name = "windows_x86_64_gnu" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" - [[package]] name = "windows_x86_64_gnu" version = "0.42.1" @@ -3236,12 +3311,6 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" -[[package]] -name = "windows_x86_64_msvc" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" - [[package]] name = "windows_x86_64_msvc" version = "0.42.1" @@ -3287,12 +3356,6 @@ dependencies = [ "libc", ] -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "zeroize" version = "1.5.7" @@ -3313,3 +3376,33 @@ dependencies = [ "syn 1.0.107", "synstructure", ] + +[[package]] +name = "zstd" +version = "0.12.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.4+zstd.1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.7+zstd.1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/trifid-api/.cargo/config.toml b/trifid-api/.cargo/config.toml deleted file mode 100644 index a7194eb..0000000 --- a/trifid-api/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[build] -rustc-wrapper = "sccache" \ No newline at end of file diff --git a/trifid-api/.env b/trifid-api/.env index 752d444..54dc561 100644 --- a/trifid-api/.env +++ b/trifid-api/.env @@ -1 +1 @@ -DATABASE_URL=postgres://postgres@localhost/trifidapi \ No newline at end of file +DATABASE_URL=postgres://postgres@localhost/hotel \ No newline at end of file diff --git a/trifid-api/Cargo.lock b/trifid-api/Cargo.lock deleted file mode 100644 index 54b1be2..0000000 --- a/trifid-api/Cargo.lock +++ /dev/null @@ -1,1541 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "async-stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base64" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" - -[[package]] -name = "base64" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" - -[[package]] -name = "binascii" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[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 = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" - -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cipher" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "aes-gcm", - "base64 0.20.0", - "hkdf", - "hmac", - "percent-encoding", - "rand", - "sha2", - "subtle", - "time", - "version_check", -] - -[[package]] -name = "cpufeatures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" -dependencies = [ - "libc", -] - -[[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 = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "devise" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" -dependencies = [ - "devise_codegen", - "devise_core", -] - -[[package]] -name = "devise_codegen" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" -dependencies = [ - "devise_core", - "quote", -] - -[[package]] -name = "devise_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" -dependencies = [ - "bitflags", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "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 = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[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 = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - -[[package]] -name = "figment" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" -dependencies = [ - "atomic", - "pear", - "serde", - "toml", - "uncased", - "version_check", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "futures" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" - -[[package]] -name = "futures-io" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" - -[[package]] -name = "futures-sink" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" - -[[package]] -name = "futures-task" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" - -[[package]] -name = "futures-util" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generator" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266041a359dfa931b370ef684cceb84b166beb14f7f0421f4a6a3d0c446d12e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows", -] - -[[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 = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "ghash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[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 = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[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 = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" -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 = "indexmap" -version = "1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" -dependencies = [ - "autocfg", - "hashbrown", - "serde", -] - -[[package]] -name = "inlinable_string" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - -[[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 = "itoa" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", -] - -[[package]] -name = "multer" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed4198ce7a4cbd2a57af78d28c6fbb57d81ac5f1d6ad79ac6c5587419cbdf22" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "memchr", - "mime", - "spin", - "tokio", - "tokio-util", - "version_check", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[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", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "pear" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn", -] - -[[package]] -name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "polyval" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" -dependencies = [ - "cfg-if", - "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 = "proc-macro2" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "version_check", - "yansi", -] - -[[package]] -name = "quote" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" -dependencies = [ - "proc-macro2", -] - -[[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 = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ref-cast" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c78fb8c9293bcd48ef6fce7b4ca950ceaf21210de6e105a883ee280c0f7b9ed" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "regex" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "rocket" -version = "0.5.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ead083fce4a405feb349cf09abdf64471c6077f14e0ce59364aa90d4b99317" -dependencies = [ - "async-stream", - "async-trait", - "atomic", - "atty", - "binascii", - "bytes", - "either", - "figment", - "futures", - "indexmap", - "log", - "memchr", - "multer", - "num_cpus", - "parking_lot", - "pin-project-lite", - "rand", - "ref-cast", - "rocket_codegen", - "rocket_http", - "serde", - "serde_json", - "state", - "tempfile", - "time", - "tokio", - "tokio-stream", - "tokio-util", - "ubyte", - "version_check", - "yansi", -] - -[[package]] -name = "rocket_codegen" -version = "0.5.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6aeb6bb9c61e9cd2c00d70ea267bf36f76a4cc615e5908b349c2f9d93999b47" -dependencies = [ - "devise", - "glob", - "indexmap", - "proc-macro2", - "quote", - "rocket_http", - "syn", - "unicode-xid", -] - -[[package]] -name = "rocket_http" -version = "0.5.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ded65d127954de3c12471630bf4b81a2792f065984461e65b91d0fdaafc17a2" -dependencies = [ - "cookie", - "either", - "futures", - "http", - "hyper", - "indexmap", - "log", - "memchr", - "pear", - "percent-encoding", - "pin-project-lite", - "ref-cast", - "serde", - "smallvec", - "stable-pattern", - "state", - "time", - "tokio", - "uncased", -] - -[[package]] -name = "rustversion" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" - -[[package]] -name = "ryu" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "spin" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" - -[[package]] -name = "stable-pattern" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" -dependencies = [ - "memchr", -] - -[[package]] -name = "state" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" -dependencies = [ - "loom", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -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 = "tokio" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys", -] - -[[package]] -name = "tokio-macros" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[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.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "trifid" -version = "0.1.0" -dependencies = [ - "base64 0.21.0", - "log", - "rocket", -] - -[[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.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "ubyte" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" -dependencies = [ - "serde", -] - -[[package]] -name = "uncased" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" -dependencies = [ - "serde", - "version_check", -] - -[[package]] -name = "unicode-ident" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "universal-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "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 = "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-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" -dependencies = [ - "windows_aarch64_msvc 0.39.0", - "windows_i686_gnu 0.39.0", - "windows_i686_msvc 0.39.0", - "windows_x86_64_gnu 0.39.0", - "windows_x86_64_msvc 0.39.0", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" - -[[package]] -name = "windows_i686_gnu" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" - -[[package]] -name = "windows_i686_msvc" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/trifid-api/Cargo.toml b/trifid-api/Cargo.toml index d63dc22..b9cfbd1 100644 --- a/trifid-api/Cargo.toml +++ b/trifid-api/Cargo.toml @@ -6,23 +6,17 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rocket = { version = "0.5.0-rc.2", features = ["json"] } -base64 = "0.21.0" -log = "0.4.17" -sqlx = { version = "0.6", features = [ "runtime-tokio-native-tls" , "postgres" ] } -tokio = { version = "1", features = ["full"] } -toml = "0.7.1" -serde = "1.0.152" -dotenvy = "0.15.6" -paste = "1.0.11" -totp-rs = { version = "4.2.0", features = ["qr", "otpauth", "gen_secret"]} -uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics"]} -url = { version = "2.3.1", features = ["serde"] } -urlencoding = "2.1.2" -chrono = "0.4.23" -aes-gcm = "0.10.1" -hex = "0.4.3" -rand = "0.8.5" -trifid-pki = { version = "0.1.3", path = "../trifid-pki" } -sha2 = "0.10.6" -ipnet = { version = "2.7.1", features = ["serde"] } +actix-web = "4" # Web framework + +serde = { version = "1", features = ["derive"] } # Serialization and deserialization + +once_cell = "1" # Config +toml = "0.7" # Config + +log = "0.4" # Logging +simple_logger = "4" # Logging + +sea-orm = { version = "^0", features = [ "sqlx-postgres", "runtime-actix-rustls", "macros" ]} # Database + +rand = "0.8" # Misc. +hex = "0.4" # Misc. \ No newline at end of file diff --git a/trifid-api/build.rs b/trifid-api/build.rs index d658ea5..3c284bb 100644 --- a/trifid-api/build.rs +++ b/trifid-api/build.rs @@ -1,20 +1,3 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// generated by `sqlx migrate build-script` fn main() { - // trigger recompilation when a new migration is added - println!("cargo:rerun-if-changed=migrations"); + println!("cargo:rerun-if-changed=migrations/"); } \ No newline at end of file diff --git a/trifid-api/config.example.toml b/trifid-api/config.example.toml deleted file mode 100644 index 921f189..0000000 --- a/trifid-api/config.example.toml +++ /dev/null @@ -1,81 +0,0 @@ -################################## -# trifid-api example config file # -################################## -# trifid-api, an open source reimplementation of the Defined Networking nebula management server. -# Copyright (C) 2023 c0repwn3r -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please read this file in it's entirety to learn what options you do or don't need to change -# to get a functional trifid-api instance. - -# What port should the API server listen on? -# e.g. 8000 would mean the server is reachable at localhost:8000. -# You probably don't need to change this. -listen_port = 8000 - -# What is the postgres connection url to connect to the database? -# Example: postgres://username:password@database_host/database_name -# You absolutely need to change this. -db_url = "postgres://postgres@localhost/trifidapi" - -# What is the externally accessible URL of this instance? -# If you are running behind a reverse proxy, or a domain name, or similar, -# you need to set this to the URL that the web UI can make requests to. -# e.g. http://localhost:8000 -# Reminder: this ip needs to be internet-accessible. -# You absolutely need to change this. -base = "http://localhost:8000" - -# What is the externally accessible URL of the **web ui** for this instance? -# This URL will be used to generate magic links, and needs to be correct. -# You absolutely need to change this. -web_root = "http://localhost:5173" - -# How long should magic links be valid for (in seconds)? -# You probably don't need to change this, 86400 (24 hours) is a sane default. -magic_links_valid_for = 86400 - -# How long should session tokens be valid for (in seconds)? -# This controls how long a user can go without requesting a new "magic link" to re-log-in. -# This is a completley independent timer than `totp_verification_valid_for` - the auth token can (and often will) expire -# while the session token remains completley valid. -# You probably don't need to change this, 86400 (24 hours) is a sane default. -session_tokens_valid_for = 86400 - -# How long should 2FA authentication be valid for (in seconds)? -# This controls how long a user can remain logged in without having to re-do the 2FA authentication process. -# This is a completley independent timer than `session_tokens_valid_for` - the session token can expire while the 2FA token -# remains completley valid. -# You probably don't need to change this, 3600 (1 hour) is a sane default. -totp_verification_valid_for = 3600 - -# The per-instance data encryption key to protect sensitive data in the instance. -# YOU ABSOLUTELY NEED TO CHANGE THIS. If you don't change anything else in this file, this should be the one thing you change. - -# This should be a 32-byte hex value. Generate it with `openssl rand -hex 32`, or any other tool of your choice. -# If you get "InvalidLength" errors while trying to do anything involving organizations, that indicates that this -# value was improperly generated. -# -# ------- WARNING ------- -# Do not change this value in a production instance. It will make existing data inaccessible until changed back. -# ------- WARNING ------- -data_key = "edd600bcebea461381ea23791b6967c8667e12827ac8b94dc022f189a5dc59a2" - -# How long should CA certs be valid for before they need to be replaced (in seconds)? -# This controls the maximum amount of time a network on this instance can go -# without a rekey. -# You probably don't need to change, this, 31536000 (1 year) is a sane default. -# This value only affects new certs signed by this instance. -ca_certs_valid_for = 31536000 \ No newline at end of file diff --git a/trifid-api/config.toml b/trifid-api/config.toml deleted file mode 100644 index f206eff..0000000 --- a/trifid-api/config.toml +++ /dev/null @@ -1,9 +0,0 @@ -listen_port = 8000 -db_url = "postgres://postgres@localhost/trifidapi" -base = "http://localhost:8000" -web_root = "http://localhost:5173" -magic_links_valid_for = 86400 -session_tokens_valid_for = 86400 -totp_verification_valid_for = 3600 -data_key = "edd600bcebea461381ea23791b6967c8667e12827ac8b94dc022f189a5dc59a2" -ca_certs_valid_for = 31536000 \ No newline at end of file diff --git a/trifid-api/diesel.toml b/trifid-api/diesel.toml new file mode 100644 index 0000000..4ae5e4b --- /dev/null +++ b/trifid-api/diesel.toml @@ -0,0 +1,5 @@ +[print_schema] +file = "src/schema.rs" + +[migrations_directory] +dir = "migrations" \ No newline at end of file diff --git a/trifid-api/migrations/20230204174853_create_users.sql b/trifid-api/migrations/20230204174853_create_users.sql deleted file mode 100644 index 53fce23..0000000 --- a/trifid-api/migrations/20230204174853_create_users.sql +++ /dev/null @@ -1,29 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE users ( - id SERIAL NOT NULL PRIMARY KEY, - email VARCHAR(320) NOT NULL UNIQUE, - created_on INTEGER NOT NULL, -- Unix (seconds) timestamp of user creation - - banned INTEGER NOT NULL, -- Is the user banned? 1=Yes 0=No - ban_reason VARCHAR(1024) NOT NULL, -- What is the reason for this user's ban? - - totp_secret VARCHAR(128) NOT NULL, - totp_verified INTEGER NOT NULL, - totp_otpurl VARCHAR(3000) NOT NULL -); -CREATE INDEX idx_users_email ON users(email); \ No newline at end of file diff --git a/trifid-api/migrations/20230204185754_magic_links.sql b/trifid-api/migrations/20230204185754_magic_links.sql deleted file mode 100644 index 889ddb2..0000000 --- a/trifid-api/migrations/20230204185754_magic_links.sql +++ /dev/null @@ -1,21 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE magic_links ( - id VARCHAR(39) NOT NULL PRIMARY KEY UNIQUE, - user_id SERIAL NOT NULL REFERENCES users(id), - expires_on INTEGER NOT NULL -- Unix (seconds) timestamp of when this link expires -); \ No newline at end of file diff --git a/trifid-api/migrations/20230206012409_create_session_tokens.sql b/trifid-api/migrations/20230206012409_create_session_tokens.sql deleted file mode 100644 index e7d0133..0000000 --- a/trifid-api/migrations/20230206012409_create_session_tokens.sql +++ /dev/null @@ -1,21 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE session_tokens ( - id VARCHAR(39) NOT NULL PRIMARY KEY, - user_id SERIAL NOT NULL REFERENCES users(id), - expires_on INTEGER NOT NULL -- Unix (seconds) timestamp of when this session expires -); \ No newline at end of file diff --git a/trifid-api/migrations/20230206031048_create_auth_tokens.sql b/trifid-api/migrations/20230206031048_create_auth_tokens.sql deleted file mode 100644 index 23c9b5e..0000000 --- a/trifid-api/migrations/20230206031048_create_auth_tokens.sql +++ /dev/null @@ -1,21 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE auth_tokens ( - id VARCHAR(39) NOT NULL PRIMARY KEY, - user_id SERIAL NOT NULL REFERENCES users(id), - session_token VARCHAR(39) NOT NULL REFERENCES session_tokens(id) -); \ No newline at end of file diff --git a/trifid-api/migrations/20230207145453_create_totp_tokens.sql b/trifid-api/migrations/20230207145453_create_totp_tokens.sql deleted file mode 100644 index 86b493c..0000000 --- a/trifid-api/migrations/20230207145453_create_totp_tokens.sql +++ /dev/null @@ -1,22 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE totp_create_tokens ( - id VARCHAR(41) NOT NULL PRIMARY KEY, - expires_on INTEGER NOT NULL, -- The unix (seconds) timestamp of when this TOTP create token expires - totp_otpurl VARCHAR(3000) NOT NULL, - totp_secret VARCHAR(128) NOT NULL -); \ No newline at end of file diff --git a/trifid-api/migrations/20230224000741_create_orgs.sql b/trifid-api/migrations/20230224000741_create_orgs.sql deleted file mode 100644 index 5a50f13..0000000 --- a/trifid-api/migrations/20230224000741_create_orgs.sql +++ /dev/null @@ -1,24 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE organizations ( - id SERIAL NOT NULL PRIMARY KEY, - owner SERIAL NOT NULL REFERENCES users(id), - ca_key VARCHAR(3072) NOT NULL, -- The hex-encoded ENCRYPTED (see below) concatenation of all CA keys on this org - ca_crt VARCHAR(3072) NOT NULL, -- The concatenation of all CA certificates on this org. This is passed directly to NebulaCAPool - iv VARCHAR(128) NOT NULL -- The 12-byte hex-encoded IV, used to encrypt ca_key with the instance AES key -); -CREATE INDEX idx_organizations_owner ON organizations(owner); \ No newline at end of file diff --git a/trifid-api/migrations/20230226020713_create_orgs_authorized_users.sql b/trifid-api/migrations/20230226020713_create_orgs_authorized_users.sql deleted file mode 100644 index 530b9e4..0000000 --- a/trifid-api/migrations/20230226020713_create_orgs_authorized_users.sql +++ /dev/null @@ -1,23 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE organization_authorized_users ( - id SERIAL NOT NULL PRIMARY KEY, - user_id SERIAL NOT NULL REFERENCES users(id), - org_id SERIAL NOT NULL REFERENCES organizations(id) -); -CREATE INDEX idx_organization_authorized_users_user ON organization_authorized_users(user_id); -CREATE INDEX idx_organization_authorized_users_org ON organization_authorized_users(org_id); \ No newline at end of file diff --git a/trifid-api/migrations/20230228132411_add_cacheddata.sql b/trifid-api/migrations/20230228132411_add_cacheddata.sql deleted file mode 100644 index 169105d..0000000 --- a/trifid-api/migrations/20230228132411_add_cacheddata.sql +++ /dev/null @@ -1,20 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE cacheddata ( - datakey VARCHAR(256) NOT NULL PRIMARY KEY, - datavalue VARCHAR(2048) NOT NULL -); \ No newline at end of file diff --git a/trifid-api/migrations/20230302220748_add_roles.sql b/trifid-api/migrations/20230302220748_add_roles.sql deleted file mode 100644 index 54c1b55..0000000 --- a/trifid-api/migrations/20230302220748_add_roles.sql +++ /dev/null @@ -1,22 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE roles ( - id SERIAL NOT NULL PRIMARY KEY, - org SERIAL NOT NULL REFERENCES organizations(id), - name VARCHAR(128) NOT NULL, - description VARCHAR(4096) NOT NULL -); \ No newline at end of file diff --git a/trifid-api/migrations/20230302220808_add_firewall_rules.sql b/trifid-api/migrations/20230302220808_add_firewall_rules.sql deleted file mode 100644 index 69961af..0000000 --- a/trifid-api/migrations/20230302220808_add_firewall_rules.sql +++ /dev/null @@ -1,27 +0,0 @@ --- trifid-api, an open source reimplementation of the Defined Networking nebula management server. --- Copyright (C) 2023 c0repwn3r --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE roles_firewall_rules ( - id SERIAL NOT NULL PRIMARY KEY, - role SERIAL NOT NULL REFERENCES roles(id), - protocol INTEGER NOT NULL, -- 0: any 1: tcp 2: udp 3: icmp - port_range_start INTEGER NOT NULL, -- min: 1 max: 65535. Ignored if protocol==3 - port_range_end INTEGER NOT NULL, -- min: 1 max: 65535, must be greater than or equal to port_range_start. Ignored if protocol==3 - allow_from INTEGER NOT NULL, -- Allow traffic goverened by above rules from who? - -- -1: anybody - -- (a role, anything else): only that role - description VARCHAR(4096) NOT NULL -); \ No newline at end of file diff --git a/trifid-api/src/auth.rs b/trifid-api/src/auth.rs deleted file mode 100644 index cf399af..0000000 --- a/trifid-api/src/auth.rs +++ /dev/null @@ -1,144 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::http::Status; -use rocket::{Request}; -use rocket::request::{FromRequest, Outcome}; -use crate::tokens::{validate_auth_token, validate_session_token}; - -pub struct PartialUserInfo { - pub user_id: i32, - pub created_at: i64, - pub email: String, - pub has_totp_auth: bool, - - pub session_id: String, - pub auth_id: Option -} - -#[derive(Debug)] -pub enum AuthenticationError { - MissingToken, - InvalidToken(usize), - DatabaseError, - RequiresTOTP -} - -#[rocket::async_trait] -impl<'r> FromRequest<'r> for PartialUserInfo { - type Error = AuthenticationError; - - async fn from_request(req: &'r Request<'_>) -> Outcome { - let headers = req.headers(); - - // make sure the bearer token exists - if let Some(authorization) = headers.get_one("Authorization") { - // parse bearer token - let components = authorization.split(' ').collect::>(); - - if components.len() != 2 && components.len() != 3 { - return Outcome::Failure((Status::Unauthorized, AuthenticationError::MissingToken)); - } - - if components[0] != "Bearer" { - return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(0))); - } - - if components.len() == 2 && !components[1].starts_with("st-") { - return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(1))); - } - - let st: String; - let user_id: i64; - let at: Option; - - match &components[1][..3] { - "st-" => { - // validate session token - st = components[1].to_string(); - match validate_session_token(st.clone(), req.rocket().state().unwrap()).await { - Ok(uid) => user_id = uid, - Err(_) => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(2))) - } - }, - _ => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(3))) - } - - if components.len() == 3 { - match &components[2][..3] { - "at-" => { - // validate auth token - at = Some(components[2].to_string()); - match validate_auth_token(at.clone().unwrap().clone(), st.clone(), req.rocket().state().unwrap()).await { - Ok(_) => (), - Err(_) => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(4))) - } - }, - _ => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(5))) - } - } else { - at = None; - } - - // this user is 100% valid and authenticated, fetch their info - - let user = match sqlx::query!("SELECT * FROM users WHERE id = $1", user_id.clone() as i32).fetch_one(req.rocket().state().unwrap()).await { - Ok(u) => u, - Err(_) => return Outcome::Failure((Status::InternalServerError, AuthenticationError::DatabaseError)) - }; - - Outcome::Success(PartialUserInfo { - user_id: user_id as i32, - created_at: user.created_on as i64, - email: user.email, - has_totp_auth: at.is_some(), - session_id: st, - auth_id: at, - }) - } else { - Outcome::Failure((Status::Unauthorized, AuthenticationError::MissingToken)) - } - } -} - -pub struct TOTPAuthenticatedUserInfo { - pub user_id: i32, - pub created_at: i64, - pub email: String, -} -#[rocket::async_trait] -impl<'r> FromRequest<'r> for TOTPAuthenticatedUserInfo { - type Error = AuthenticationError; - - async fn from_request(request: &'r Request<'_>) -> Outcome { - let userinfo = PartialUserInfo::from_request(request).await; - match userinfo { - Outcome::Failure(e) => Outcome::Failure(e), - Outcome::Forward(f) => Outcome::Forward(f), - Outcome::Success(s) => { - if s.has_totp_auth { - Outcome::Success(Self { - user_id: s.user_id, - created_at: s.created_at, - email: s.email, - }) - } else { - Outcome::Failure((Status::Unauthorized, AuthenticationError::RequiresTOTP)) - } - } - } - } -} \ No newline at end of file diff --git a/trifid-api/src/config.rs b/trifid-api/src/config.rs index 954a4f7..6abdc18 100644 --- a/trifid-api/src/config.rs +++ b/trifid-api/src/config.rs @@ -1,31 +1,51 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . +use std::fs; +use log::error; +use once_cell::sync::Lazy; +use serde::{Serialize, Deserialize}; -use serde::Deserialize; -use url::Url; +pub static CONFIG: Lazy = Lazy::new(|| { + let config_str = match fs::read_to_string("/etc/trifid/config.toml") { + Ok(str) => str, + Err(e) => { + error!("Unable to read config file: {}", e); + std::process::exit(1); + } + }; -#[derive(Deserialize)] -pub struct TFConfig { - pub listen_port: u16, - pub db_url: String, - pub base: Url, - pub web_root: Url, - pub magic_links_valid_for: u64, - pub session_tokens_valid_for: u64, - pub totp_verification_valid_for: u64, - pub data_key: String, - pub ca_certs_valid_for: u64 -} \ No newline at end of file + match toml::from_str(&config_str) { + Ok(cfg) => cfg, + Err(e) => { + error!("Unable to parse config file: {}", e); + std::process::exit(1); + } + } +}); + +#[derive(Serialize, Debug, Deserialize)] +pub struct TrifidConfig { + pub database: TrifidConfigDatabase +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct TrifidConfigDatabase { + pub url: String, + #[serde(default = "max_connections_default")] + pub max_connections: u32, + #[serde(default = "min_connections_default")] + pub min_connections: u32, + #[serde(default = "time_defaults")] + pub connect_timeout: u64, + #[serde(default = "time_defaults")] + pub acquire_timeout: u64, + #[serde(default = "time_defaults")] + pub idle_timeout: u64, + #[serde(default = "time_defaults")] + pub max_lifetime: u64, + #[serde(default = "sqlx_logging_default")] + pub sqlx_logging: bool +} + +fn max_connections_default() -> u32 { 100 } +fn min_connections_default() -> u32 { 5 } +fn time_defaults() -> u64 { 8 } +fn sqlx_logging_default() -> bool { true } \ No newline at end of file diff --git a/trifid-api/src/crypto.rs b/trifid-api/src/crypto.rs deleted file mode 100644 index bb879de..0000000 --- a/trifid-api/src/crypto.rs +++ /dev/null @@ -1,43 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::error::Error; -use aes_gcm::{Aes256Gcm, KeyInit, Nonce}; -use aes_gcm::aead::{Aead, Payload}; -use rand::Rng; -use rand::rngs::OsRng; -use crate::config::TFConfig; - -pub fn get_cipher_from_config(config: &TFConfig) -> Result> { - let key_slice = hex::decode(&config.data_key)?; - Ok(Aes256Gcm::new_from_slice(&key_slice)?) -} - -pub fn encrypt_with_nonce(plaintext: &[u8], nonce: [u8; 12], cipher: &Aes256Gcm) -> Result, aes_gcm::Error> { - let nonce = Nonce::from_slice(&nonce); - let ciphertext = cipher.encrypt(nonce, plaintext)?; - Ok(ciphertext) -} - -pub fn decrypt_with_nonce(ciphertext: &[u8], nonce: [u8; 12], cipher: &Aes256Gcm) -> Result, aes_gcm::Error> { - let nonce = Nonce::from_slice(&nonce); - let plaintext = cipher.decrypt(nonce, Payload::from(ciphertext))?; - Ok(plaintext) -} - -pub fn generate_random_iv() -> [u8; 12] { - OsRng.gen() -} \ No newline at end of file diff --git a/trifid-api/src/db.rs b/trifid-api/src/db.rs deleted file mode 100644 index e15090a..0000000 --- a/trifid-api/src/db.rs +++ /dev/null @@ -1,15 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . \ No newline at end of file diff --git a/trifid-api/src/format.rs b/trifid-api/src/format.rs deleted file mode 100644 index d193d65..0000000 --- a/trifid-api/src/format.rs +++ /dev/null @@ -1,98 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::fmt::{Display, Formatter}; -use crate::format::PEMValidationError::{IncorrectSegmentLength, InvalidBase64Data, MissingStartSentinel}; -use crate::util::base64decode; - -pub const ED_PUBKEY_START_STR: &str = "-----BEGIN NEBULA ED25519 PUBLIC KEY-----"; -pub const ED_PUBKEY_END_STR: &str = "-----END NEBULA ED25519 PUBLIC KEY-----"; - -pub const DH_PUBKEY_START_STR: &str = "-----BEGIN NEBULA X25519 PUBLIC KEY-----"; -pub const DH_PUBKEY_END_STR: &str = "-----END NEBULA X25519 PUBLIC KEY-----"; - -pub enum PEMValidationError { - MissingStartSentinel, - InvalidBase64Data, - MissingEndSentinel, - IncorrectSegmentLength(usize, usize) -} -impl Display for PEMValidationError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Self::MissingEndSentinel => write!(f, "Missing ending sentinel"), - Self::MissingStartSentinel => write!(f, "Missing starting sentinel"), - Self::InvalidBase64Data => write!(f, "invalid base64 data"), - Self::IncorrectSegmentLength(expected, got) => write!(f, "incorrect number of segments, expected {} got {}", expected, got) - } - } -} - -pub fn validate_ed_pubkey_pem(pubkey: &str) -> Result<(), PEMValidationError> { - let segments = pubkey.split('\n'); - let segs = segments.collect::>(); - if segs.len() < 3 { - return Err(IncorrectSegmentLength(3, segs.len())) - } - if segs[0] != ED_PUBKEY_START_STR { - return Err(MissingStartSentinel) - } - if base64decode(segs[1]).is_err() { - return Err(InvalidBase64Data) - } - if segs[2] != ED_PUBKEY_END_STR { - return Err(MissingStartSentinel) - } - Ok(()) -} - -pub fn validate_dh_pubkey_pem(pubkey: &str) -> Result<(), PEMValidationError> { - let segments = pubkey.split('\n'); - let segs = segments.collect::>(); - if segs.len() < 3 { - return Err(IncorrectSegmentLength(3, segs.len())) - } - if segs[0] != DH_PUBKEY_START_STR { - return Err(MissingStartSentinel) - } - if base64decode(segs[1]).is_err() { - return Err(InvalidBase64Data) - } - if segs[2] != DH_PUBKEY_END_STR { - return Err(MissingStartSentinel) - } - Ok(()) -} - -pub fn validate_ed_pubkey_base64(pubkey: &str) -> Result<(), PEMValidationError> { - match base64decode(pubkey) { - Ok(k) => validate_ed_pubkey_pem(match std::str::from_utf8(k.as_ref()) { - Ok(k) => k, - Err(_) => return Err(InvalidBase64Data) - }), - Err(_) => Err(InvalidBase64Data) - } -} - -pub fn validate_dh_pubkey_base64(pubkey: &str) -> Result<(), PEMValidationError> { - match base64decode(pubkey) { - Ok(k) => validate_dh_pubkey_pem(match std::str::from_utf8(k.as_ref()) { - Ok(k) => k, - Err(_) => return Err(InvalidBase64Data) - }), - Err(_) => Err(InvalidBase64Data) - } -} \ No newline at end of file diff --git a/trifid-api/src/kv.rs b/trifid-api/src/kv.rs deleted file mode 100644 index 15ccb05..0000000 --- a/trifid-api/src/kv.rs +++ /dev/null @@ -1,28 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::error::Error; -use sqlx::PgPool; - -pub async fn kv_get<'a>(key: &'a str, db: &PgPool) -> Result, Box> { - let res = sqlx::query!("SELECT datavalue FROM cacheddata WHERE datakey = $1", key).fetch_optional(db).await?; - Ok(res.map(|i| i.datavalue)) -} - -pub async fn kv_set(key: &str, value: &str, db: &PgPool) -> Result<(), Box> { - sqlx::query!("INSERT INTO cacheddata (datakey, datavalue) VALUES ($2, $1) ON CONFLICT (datakey) DO UPDATE SET datavalue = $1", value, key).execute(db).await?; - Ok(()) -} \ No newline at end of file diff --git a/trifid-api/src/main.rs b/trifid-api/src/main.rs index 847c3b1..0ef408b 100644 --- a/trifid-api/src/main.rs +++ b/trifid-api/src/main.rs @@ -1,213 +1,35 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -extern crate core; - use std::error::Error; -use std::fs; -use std::path::Path; -use dotenvy::dotenv; -use log::{error, info}; -use rocket::{catchers, Request, Response, routes}; -use rocket::fairing::{Fairing, Info, Kind}; -use rocket::http::Header; -use sha2::Sha256; -use sqlx::migrate::Migrator; -use sqlx::postgres::PgPoolOptions; -use crate::config::TFConfig; -use crate::kv::{kv_get, kv_set}; -use sha2::Digest; +use std::time::Duration; +use actix_web::{App, HttpResponse, HttpServer, post, web::{Data, Json, JsonConfig}}; +use log::{error, info, Level}; +use sea_orm::{ConnectOptions, Database, DatabaseConnection}; +use serde::{Serialize, Deserialize}; +use crate::config::CONFIG; + -pub mod format; -pub mod util; -pub mod db; pub mod config; -pub mod tokens; -pub mod routes; -pub mod auth; -pub mod crypto; -pub mod org; -pub mod kv; -pub mod role; -static MIGRATOR: Migrator = sqlx::migrate!(); - -pub struct CORS; - -#[rocket::async_trait] -impl Fairing for CORS { - fn info(&self) -> Info { - Info { - name: "Add CORS headers to responses", - kind: Kind::Response, - } - } - - async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) { - response.set_header(Header::new("Access-Control-Allow-Origin", "*")); - response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS")); - response.set_header(Header::new("Access-Control-Allow-Headers", "*")); - response.set_header(Header::new("Access-Control-Allow-Credentials", "true")); - } -} - -#[rocket::main] +#[actix_web::main] async fn main() -> Result<(), Box> { - let _ = rocket::build(); + simple_logger::init_with_level(Level::Debug).unwrap(); - info!("[tfapi] loading config"); + info!("Connecting to database at {}...", CONFIG.database.url); - let _ = dotenv(); + let mut opt = ConnectOptions::new(CONFIG.database.url.clone()); + opt.max_connections(CONFIG.database.max_connections) + .min_connections(CONFIG.database.min_connections) + .connect_timeout(Duration::from_secs(CONFIG.database.connect_timeout)) + .acquire_timeout(Duration::from_secs(CONFIG.database.acquire_timeout)) + .idle_timeout(Duration::from_secs(CONFIG.database.idle_timeout)) + .max_lifetime(Duration::from_secs(CONFIG.database.max_lifetime)) + .sqlx_logging(CONFIG.database.sqlx_logging) + .sqlx_logging_level(log::LevelFilter::Info); - if std::env::var("CONFIG_FILE").is_err() && !Path::new("config.toml").exists() { - error!("[tfapi] fatal: the environment variable CONFIG_FILE is not set"); - error!("[tfapi] help: try creating a .env file that sets it"); - error!("[tfapi] help: or, create a file config.toml with your config, as it is loaded automatically"); - std::process::exit(1); - } + let db = Database::connect(opt).await?; - let config_file = if Path::new("config.toml").exists() { - "config.toml".to_string() - } else { - std::env::var("CONFIG_FILE").unwrap() - }; - let config_data = match fs::read_to_string(&config_file) { - Ok(d) => d, - Err(e) => { - error!("[tfapi] fatal: unable to read config from {}", config_file); - error!("[tfapi] fatal: {}", e); - std::process::exit(1); - } - }; - let config: TFConfig = match toml::from_str(&config_data) { - Ok(c) => c, - Err(e) => { - error!("[tfapi] fatal: unable to parse config from {}", config_file); - error!("[tfapi] fatal: {}", e); - std::process::exit(1); - } - }; - info!("[tfapi] connecting to database pool"); - - let pool = match PgPoolOptions::new().max_connections(5).connect(&config.db_url).await { - Ok(p) => p, - Err(e) => { - error!("[tfapi] fatal: unable to connect to database pool"); - error!("[tfapi] fatal: {}", e); - std::process::exit(1); - } - }; - - info!("[tfapi] running database migrations"); - - MIGRATOR.run(&pool).await?; - - info!("[tfapi] verifying encryption key"); - - let kv_hash = kv_get("pmk_hash", &pool).await.expect("Unable to get pmk hash from kv store"); - - let mut hasher = Sha256::new(); - hasher.update(config.data_key.as_bytes()); - let config_hash = hex::encode(hasher.finalize()); - if let Some(k_hash) = kv_hash { - if config_hash != k_hash { - error!("[tfapi] fatal: instance master key does not match key used to encrypt data"); - error!("[tfapi] fatal: datastore was encrypted with keyid {k_hash}"); - error!("[tfapi] fatal: the key in your config has the keyid {config_hash}"); - error!("[tfapi] fatal: you probably changed data_key. please return it to it's original value"); - std::process::exit(1); - } else { - info!("[tfapi] data keyid is {config_hash}"); - } - } else { - info!("[tfapi] detected first run"); - info!("[tfapi] welcome to trifid!"); - info!("[tfapi] data keyid is {config_hash}"); - - if let Err(e) = kv_set("pmk_hash", config_hash.as_str(), &pool).await { - error!("[tfapi] fatal: unable to set pmk_hash in kv store"); - error!("[tfapi] fatal: the database returned the following error:"); - error!("[tfapi] fatal: {e}"); - std::process::exit(1); - } else { - info!("[tfapi] configured instance information in kv store"); - } - } - - info!("[tfapi] building rocket config"); - - let figment = rocket::Config::figment().merge(("port", config.listen_port)); - - let _ = rocket::custom(figment) - .mount("/", routes![ - crate::routes::v1::auth::magic_link::magiclink_request, - crate::routes::v1::auth::magic_link::options, - crate::routes::v1::signup::signup_request, - crate::routes::v1::signup::options, - crate::routes::v1::auth::verify_magic_link::verify_magic_link, - crate::routes::v1::auth::verify_magic_link::options, - crate::routes::v1::totp_authenticators::totp_authenticators_request, - crate::routes::v1::totp_authenticators::options, - crate::routes::v1::verify_totp_authenticator::verify_totp_authenticator_request, - crate::routes::v1::verify_totp_authenticator::options, - crate::routes::v1::auth::totp::totp_request, - crate::routes::v1::auth::totp::options, - crate::routes::v1::auth::check_session::check_session, - crate::routes::v1::auth::check_session::check_session_auth, - crate::routes::v1::auth::check_session::options, - crate::routes::v1::auth::check_session::options_auth, - crate::routes::v2::whoami::whoami_request, - crate::routes::v2::whoami::options, - - crate::routes::v1::organization::options, - crate::routes::v1::organization::orgidoptions, - crate::routes::v1::organization::orginfo_req, - crate::routes::v1::organization::orglist_req, - crate::routes::v1::organization::create_org, - crate::routes::v1::user::get_user, - crate::routes::v1::user::options, - crate::routes::v1::organization::createorgoptions, - crate::routes::v1::ca::get_cas_for_org, - crate::routes::v1::ca::options, - crate::routes::v1::roles::get_roles, - crate::routes::v1::roles::options, - crate::routes::v1::roles::options_roleadd, - crate::routes::v1::roles::role_add - ]) - .register("/", catchers![ - crate::routes::handler_400, - crate::routes::handler_401, - crate::routes::handler_403, - crate::routes::handler_404, - crate::routes::handler_422, - - crate::routes::handler_500, - crate::routes::handler_501, - crate::routes::handler_502, - crate::routes::handler_503, - crate::routes::handler_504, - crate::routes::handler_505, - ]) - .attach(CORS) - .manage(pool) - .manage(config) - .launch().await?; Ok(()) -} \ No newline at end of file +} diff --git a/trifid-api/src/org.rs b/trifid-api/src/org.rs deleted file mode 100644 index 501b14a..0000000 --- a/trifid-api/src/org.rs +++ /dev/null @@ -1,77 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::error::Error; - -use rocket::form::validate::Contains; -use sqlx::PgPool; -use trifid_pki::ca::NebulaCAPool; - -pub async fn get_org_by_owner_id(user: i32, db: &PgPool) -> Result, Box> { - - Ok(sqlx::query!("SELECT id FROM organizations WHERE owner = $1", user).fetch_optional(db).await?.map(|r| r.id)) -} - -pub async fn get_orgs_by_assoc_id(user: i32, db: &PgPool) -> Result, Box> { - let res: Vec<_> = sqlx::query!("SELECT org_id FROM organization_authorized_users WHERE user_id = $1", user).fetch_all(db).await?; - - let mut ret = vec![]; - - for i in res { - ret.push(i.org_id); - } - - Ok(ret) -} - -pub async fn get_users_by_assoc_org(org: i32, db: &PgPool) -> Result, Box> { - let res: Vec<_> = sqlx::query!("SELECT user_id FROM organization_authorized_users WHERE org_id = $1", org).fetch_all(db).await?; - - let mut ret = vec![]; - - for i in res { - ret.push(i.user_id); - } - - Ok(ret) -} - -pub async fn get_associated_orgs(user: i32, db: &PgPool) -> Result, Box> { - let mut assoc_orgs = vec![]; - - if let Some(owned_org) = get_org_by_owner_id(user, db).await? { - assoc_orgs.push(owned_org); - } - - assoc_orgs.append(&mut get_orgs_by_assoc_id(user, db).await?); - - Ok(assoc_orgs) -} - -pub async fn user_has_org_assoc(user: i32, org: i32, db: &PgPool) -> Result> { - let associated_orgs = get_associated_orgs(user, db).await?; - - Ok(associated_orgs.contains(org)) -} - -pub async fn get_org_ca_pool(org: i32, db: &PgPool) -> Result> { - // get CAPool PEM from db - let pem = sqlx::query!("SELECT ca_crt FROM organizations WHERE id = $1", org).fetch_one(db).await?.ca_crt; - - let ca_pool = NebulaCAPool::new_from_pem(&hex::decode(pem)?)?; - - Ok(ca_pool) -} \ No newline at end of file diff --git a/trifid-api/src/role.rs b/trifid-api/src/role.rs deleted file mode 100644 index 5660964..0000000 --- a/trifid-api/src/role.rs +++ /dev/null @@ -1,98 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::error::Error; -use sqlx::PgPool; -use serde::{Serialize, Deserialize}; - -#[derive(Serialize, Deserialize)] -#[repr(i32)] -pub enum Protocol { - Any = 0, - TCP = 1, - UDP = 2, - ICMP = 3 -} - -#[derive(Serialize, Deserialize)] -pub enum AllowFrom { - Anyone, - SpecificRole(i32) -} - -#[derive(Serialize, Deserialize)] -pub struct FirewallRule { - pub id: i32, - pub protocol: Protocol, - pub port_start: u16, - pub port_end: u16, - pub allow_from: AllowFrom, - pub description: String -} - -#[derive(Serialize, Deserialize)] -pub struct Role { - pub id: i32, - pub org_id: i32, - pub name: String, - pub description: String, - pub firewall_rules: Vec -} - -pub async fn get_role(role_id: i32, db: &PgPool) -> Result, Box> { - let query_result: Option<_> = sqlx::query!("SELECT * FROM roles WHERE id = $1", role_id).fetch_optional(db).await?; - - if let Some(res) = query_result { - // get all firewall rules - let rules_res = sqlx::query!("SELECT * FROM roles_firewall_rules WHERE role = $1", Some(role_id)).fetch_all(db).await?; - - let mut rules = vec![]; - - for rule in rules_res { - rules.push(FirewallRule { - id: rule.id, - protocol: match rule.protocol { - 0 => Protocol::Any, - 1 => Protocol::TCP, - 2 => Protocol::UDP, - 3 => Protocol::ICMP, - _ => return Err(format!("invalid protocol on a firewall rule {}", rule.id).into()) - }, - port_start: rule.port_range_start as u16, - port_end: rule.port_range_end as u16, - allow_from: match rule.allow_from { - -1 => AllowFrom::Anyone, - _ => AllowFrom::SpecificRole(rule.allow_from) - }, - description: rule.description, - }) - } - - Ok(Some(Role { - id: role_id, - org_id: res.org, - name: res.name, - description: res.description, - firewall_rules: rules, - })) - } else { - Ok(None) - } -} - -pub async fn get_role_ids_for_ca(org_id: i32, db: &PgPool) -> Result, Box> { - Ok(sqlx::query!("SELECT id FROM roles WHERE org = $1", org_id).fetch_all(db).await?.iter().map(|r| r.id).collect()) -} \ No newline at end of file diff --git a/trifid-api/src/routes/mod.rs b/trifid-api/src/routes/mod.rs deleted file mode 100644 index 074561f..0000000 --- a/trifid-api/src/routes/mod.rs +++ /dev/null @@ -1,82 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pub mod v1; -pub mod v2; - -use rocket::catch; -use serde::{Serialize}; -use rocket::http::Status; - -pub const ERR_MSG_MALFORMED_REQUEST: &str = "unable to parse the request body - is it valid JSON, using correct types?"; -pub const ERR_MSG_MALFORMED_REQUEST_CODE: &str = "ERR_MALFORMED_REQUEST"; - -/* -TODO: - /v1/auth/magic-link [done] - /v1/auth/totp [done] - /v1/auth/verify-magic-link [done] - /v1/hosts/host-{id}/enrollment-code - /v1/hosts/host-{id}/enrollment-code-check - /v1/hosts/host-{id} - /v1/roles/role-{id} - /v1/feature-flags - /v1/hosts - /v1/networks - /v1/roles - /v1/signup [done] - /v1/totp-authenticators [done] - /v1/verify-totp-authenticator [done] - /v1/dnclient - /v2/enroll - /v2/whoami [in-progress] - */ - -#[derive(Serialize)] -#[serde(crate = "rocket::serde")] -pub struct APIError { - errors: Vec -} -#[derive(Serialize)] -#[serde(crate = "rocket::serde")] -pub struct APIErrorSingular { - code: String, - message: String -} - -macro_rules! error_handler { - ($code: expr, $err: expr, $msg: expr) => { - ::paste::paste! { - #[catch($code)] - pub fn []() -> (Status, String) { - (Status::from_code($code).unwrap(), format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", $err, $msg)) - } - } - }; -} -error_handler!(400, "ERR_MALFORMED_REQUEST", "unable to parse the request body, is it properly formatted?"); -error_handler!(401, "ERR_AUTHENTICATION_REQUIRED", "this endpoint requires authentication but it was not provided"); -error_handler!(403, "ERR_UNAUTHORIZED", "authorization was provided but it is expired or invalid"); -error_handler!(404, "ERR_NOT_FOUND", "resource not found"); -error_handler!(405, "ERR_METHOD_NOT_ALLOWED", "method not allowed for this endpoint"); -error_handler!(422, "ERR_MALFORMED_REQUEST", "unable to parse the request body, is it properly formatted?"); - -error_handler!(500, "ERR_QL_QUERY_FAILED", "graphql query timed out"); -error_handler!(501, "ERR_NOT_IMPLEMENTED", "query not supported by this version of graphql"); -error_handler!(502, "ERR_PROXY_ERR", "servers under load, please try again later"); -error_handler!(503, "ERR_SERVER_OVERLOADED", "servers under load, please try again later"); -error_handler!(504, "ERR_PROXY_TIMEOUT", "servers under load, please try again later"); -error_handler!(505, "ERR_CLIENT_UNSUPPORTED", "your version of dnclient is out of date, please update"); diff --git a/trifid-api/src/routes/v1/auth/check_session.rs b/trifid-api/src/routes/v1/auth/check_session.rs deleted file mode 100644 index 07b256e..0000000 --- a/trifid-api/src/routes/v1/auth/check_session.rs +++ /dev/null @@ -1,47 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::{post, options}; -use crate::auth::{PartialUserInfo, TOTPAuthenticatedUserInfo}; - -/* -These endpoints do not return any actual data, and are used purely to check auth tokens -by the client code. -Since PartialUserInfo implements FromRequest, and will error out the req even before -it gets to our handler if the auth is invalid, these reqs just have to have -it as a param. They therefore don't need to s - */ - -#[options("/v1/auth/check_session")] -pub async fn options() -> &'static str { - "" -} - -#[post("/v1/auth/check_session")] -pub async fn check_session(_user: PartialUserInfo) -> &'static str { - "ok" -} - -#[options("/v1/auth/check_auth")] -pub async fn options_auth() -> &'static str { - "" -} - - -#[post("/v1/auth/check_auth")] -pub async fn check_session_auth(_user: TOTPAuthenticatedUserInfo) -> &'static str { - "ok" -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/auth/magic_link.rs b/trifid-api/src/routes/v1/auth/magic_link.rs deleted file mode 100644 index 5706818..0000000 --- a/trifid-api/src/routes/v1/auth/magic_link.rs +++ /dev/null @@ -1,78 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::{post, State}; -use rocket::serde::json::Json; -use serde::{Serialize, Deserialize}; -use rocket::http::{ContentType, Status}; -use sqlx::PgPool; -use crate::config::TFConfig; -use crate::tokens::send_magic_link; -use rocket::options; - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct MagicLinkRequest { - pub email: String, -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct MagicLinkResponseMetadata {} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct MagicLinkResponse { - pub data: Option, - pub metadata: MagicLinkResponseMetadata, -} - - -#[options("/v1/auth/magic-link")] -pub async fn options() -> &'static str { - "" -} - -#[post("/v1/auth/magic-link", data = "")] -pub async fn magiclink_request(req: Json, pool: &State, config: &State) -> Result<(ContentType, Json), (Status, String)> { - // figure out if the user already exists - let mut id = -1; - match sqlx::query!("SELECT id FROM users WHERE email = $1", req.email.clone()).fetch_optional(pool.inner()).await { - Ok(res) => if let Some(r) = res { id = r.id as i64 }, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e))) - } - } - - if id == -1 { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_UNAUTHORIZED", "authorization was provided but it is expired or invalid"))) - } - - // send magic link to email - match send_magic_link(id, req.email.clone(), pool.inner(), config.inner()).await { - Ok(_) => (), - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e))) - } - }; - - // this endpoint doesn't actually ever return an error? it will send you the magic link no matter what - // this appears to do the exact same thing as /v1/auth/magic-link, but it doesn't check if you have an account (magic-link does) - Ok((ContentType::JSON, Json(MagicLinkResponse { - data: None, - metadata: MagicLinkResponseMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/auth/mod.rs b/trifid-api/src/routes/v1/auth/mod.rs deleted file mode 100644 index f00abb5..0000000 --- a/trifid-api/src/routes/v1/auth/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pub mod verify_magic_link; -pub mod magic_link; -pub mod totp; -pub mod check_session; \ No newline at end of file diff --git a/trifid-api/src/routes/v1/auth/totp.rs b/trifid-api/src/routes/v1/auth/totp.rs deleted file mode 100644 index dc841b6..0000000 --- a/trifid-api/src/routes/v1/auth/totp.rs +++ /dev/null @@ -1,89 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use crate::auth::PartialUserInfo; -use serde::{Serialize, Deserialize}; -use rocket::{post, State}; -use sqlx::PgPool; -use rocket::options; -use crate::tokens::{generate_auth_token, get_totpmachine, user_has_totp}; - -pub const TOTP_GENERIC_UNAUTHORIZED_ERROR: &str = "{\"errors\":[{\"code\":\"ERR_INVALID_TOTP_CODE\",\"message\":\"invalid TOTP code (maybe it expired?)\",\"path\":\"code\"}]}"; -pub const TOTP_NO_TOTP_ERROR: &str = "{\"errors\":[{\"code\":\"ERR_NO_TOTP\",\"message\":\"logged-in user does not have totp enabled\",\"path\":\"code\"}]}"; - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpRequest { - pub code: String -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpResponseData { - #[serde(rename = "authToken")] - auth_token: String -} -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpResponseMetadata { -} -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpResponse { - data: TotpResponseData, - metadata: TotpResponseMetadata -} - -#[options("/v1/auth/totp")] -pub async fn options() -> &'static str { - "" -} - - -#[post("/v1/auth/totp", data = "")] -pub async fn totp_request(req: Json, user: PartialUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { - if !match user_has_totp(user.user_id, db.inner()).await { - Ok(b) => b, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } { - return Err((Status::UnprocessableEntity, TOTP_NO_TOTP_ERROR.to_string())) - } - - if user.has_totp_auth { - return Err((Status::BadRequest, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_TOTP_ALREADY_AUTHED", "user already has valid totp authentication"))) - } - - let totpmachine = match get_totpmachine(user.user_id, db.inner()).await { - Ok(t) => t, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } - }; - - if !totpmachine.check_current(&req.0.code).unwrap_or(false) { - return Err((Status::Unauthorized, TOTP_GENERIC_UNAUTHORIZED_ERROR.to_string())) - } - - Ok((ContentType::JSON, Json(TotpResponse { - data: TotpResponseData { auth_token: match generate_auth_token(user.user_id as i64, user.session_id, db.inner()).await { - Ok(t) => t, - Err(e) => { return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) } - } }, - metadata: TotpResponseMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/auth/verify_magic_link.rs b/trifid-api/src/routes/v1/auth/verify_magic_link.rs deleted file mode 100644 index 79a4eb8..0000000 --- a/trifid-api/src/routes/v1/auth/verify_magic_link.rs +++ /dev/null @@ -1,91 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::time::{SystemTime, UNIX_EPOCH}; -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use serde::{Serialize, Deserialize}; -use rocket::{post, State}; -use sqlx::PgPool; -use crate::config::TFConfig; -use crate::tokens::generate_session_token; -use rocket::options; - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct VerifyMagicLinkRequest { - #[serde(rename = "magicLinkToken")] - pub magic_link_token: String, -} - - -#[derive(Serialize, Deserialize)] -pub struct VerifyMagicLinkResponseMetadata {} - -#[derive(Serialize, Deserialize)] -pub struct VerifyMagicLinkResponseData { - #[serde(rename = "sessionToken")] - pub session_token: String, -} - -#[derive(Serialize, Deserialize)] -pub struct VerifyMagicLinkResponse { - pub data: VerifyMagicLinkResponseData, - pub metadata: VerifyMagicLinkResponseMetadata, -} - -#[options("/v1/auth/verify-magic-link")] -pub async fn options() -> &'static str { - "" -} - - -#[post("/v1/auth/verify-magic-link", data = "")] -pub async fn verify_magic_link(req: Json, db: &State, config: &State) -> Result<(ContentType, Json), (Status, String)> { - // get the current time to check if the token is expired - let (user_id, expired_at) = match sqlx::query!("SELECT user_id, expires_on FROM magic_links WHERE id = $1", req.0.magic_link_token).fetch_one(db.inner()).await { - Ok(row) => (row.user_id, row.expires_on), - Err(e) => { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNAUTHORIZED", "this token is invalid", e))) - } - }; - let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32; - println!("expired on {}, currently {}", expired_at, current_time); - if expired_at < current_time { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_UNAUTHORIZED", "valid authorization was provided but it is expired"))) - } - - // generate session token - let token = match generate_session_token(user_id as i64, db.inner(), config.inner()).await { - Ok(t) => t, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } - }; - - // delete the token - match sqlx::query!("DELETE FROM magic_links WHERE id = $1", req.0.magic_link_token).execute(db.inner()).await { - Ok(_) => (), - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } - } - - Ok((ContentType::JSON, Json(VerifyMagicLinkResponse { - data: VerifyMagicLinkResponseData { session_token: token }, - metadata: VerifyMagicLinkResponseMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/ca.rs b/trifid-api/src/routes/v1/ca.rs deleted file mode 100644 index fe7b442..0000000 --- a/trifid-api/src/routes/v1/ca.rs +++ /dev/null @@ -1,85 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -use rocket::{options, get, State}; -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use sqlx::PgPool; - -use serde::{Serialize, Deserialize}; -use crate::auth::TOTPAuthenticatedUserInfo; -use crate::org::{get_associated_orgs, get_org_ca_pool}; - -#[options("/v1/org/<_id>/ca")] -pub fn options(_id: i32) -> &'static str { - "" -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct CaList { - pub trusted_cas: Vec, - pub blocklisted_certs: Vec -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct CA { - pub fingerprint: String, - pub cert: String -} - -#[get("/v1/org//ca")] -pub async fn get_cas_for_org(id: i32, user: TOTPAuthenticatedUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { - let associated_orgs = match get_associated_orgs(user.user_id, db.inner()).await { - Ok(r) => r, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_DB_QUERY_FAILED", "an error occurred while running the database query", e))) - }; - - if !associated_orgs.contains(&id) { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_NOT_YOUR_ORG", "you are not authorized to view details of this org"))) - } - - let ca_pool = match get_org_ca_pool(id, db.inner()).await { - Ok(pool) => pool, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"ERR_QL_QUERY_FAILED\",\"message\":\"unable to load certificates from database - {}\"}}]}}", e))); - } - }; - - let mut trusted_cas = vec![]; - - for (fingerprint, cert) in ca_pool.cas { - trusted_cas.push(CA { - fingerprint, - cert: match cert.serialize_to_pem() { - Ok(pem) => match String::from_utf8(pem) { - Ok(str) => str, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"ERR_QL_QUERY_FAILED\",\"message\":\"unable to encode one of the serialized certificates - {}\"}}]}}", e))) - }, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"ERR_QL_QUERY_FAILED\",\"message\":\"unable to serialize one of the certificates - {}\"}}]}}", e))); - } - } - }) - } - - Ok((ContentType::JSON, Json(CaList { - trusted_cas, - blocklisted_certs: ca_pool.cert_blocklist, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/mod.rs b/trifid-api/src/routes/v1/mod.rs deleted file mode 100644 index 7c0037d..0000000 --- a/trifid-api/src/routes/v1/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pub mod auth; -pub mod signup; - -pub mod totp_authenticators; -pub mod verify_totp_authenticator; -pub mod organization; -pub mod user; -pub mod ca; -pub mod roles; \ No newline at end of file diff --git a/trifid-api/src/routes/v1/organization.rs b/trifid-api/src/routes/v1/organization.rs deleted file mode 100644 index 2e2519b..0000000 --- a/trifid-api/src/routes/v1/organization.rs +++ /dev/null @@ -1,190 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::time::{Duration, SystemTime}; -use ipnet::Ipv4Net; -use rocket::{get, post, options, State, error}; -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use serde::{Serialize, Deserialize}; -use sqlx::PgPool; -use trifid_pki::cert::{NebulaCertificate, NebulaCertificateDetails, serialize_ed25519_private}; -use trifid_pki::ed25519_dalek::{SigningKey}; -use trifid_pki::rand_core::OsRng; -use crate::auth::TOTPAuthenticatedUserInfo; -use crate::config::TFConfig; -use crate::crypto::{encrypt_with_nonce, generate_random_iv, get_cipher_from_config}; -use crate::org::{get_associated_orgs, get_org_by_owner_id, get_users_by_assoc_org, user_has_org_assoc}; - -#[options("/v1/orgs")] -pub fn options() -> &'static str { - "" -} -#[options("/v1/org/<_id>")] -pub fn orgidoptions(_id: i32) -> &'static str { - "" -} -#[options("/v1/org")] -pub fn createorgoptions() -> &'static str {""} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct OrglistStruct { - pub org_ids: Vec -} - - -#[get("/v1/orgs")] -pub async fn orglist_req(user: TOTPAuthenticatedUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { - // this endpoint lists the associated organizations this user has access to - let associated_orgs = match get_associated_orgs(user.user_id, db.inner()).await { - Ok(r) => r, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_DB_QUERY_FAILED", "an error occurred while running the database query", e))) - }; - - Ok((ContentType::JSON, Json(OrglistStruct { - org_ids: associated_orgs - }))) -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct OrginfoStruct { - pub org_id: i32, - pub owner_id: i32, - pub ca_crt: String, - pub authorized_users: Vec -} - -#[get("/v1/org/")] -pub async fn orginfo_req(orgid: i32, user: TOTPAuthenticatedUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { - if !user_has_org_assoc(user.user_id, orgid, db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))? { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_MISSING_ORG_AUTHORIZATION", "this user does not have permission to access this org"))); - } - - let org = sqlx::query!("SELECT id, owner, ca_crt FROM organizations WHERE id = $1", orgid).fetch_one(db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))?; - let authorized_users = get_users_by_assoc_org(orgid, db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))?; - - Ok((ContentType::JSON, Json( - OrginfoStruct { - org_id: orgid, - owner_id: org.owner, - ca_crt: org.ca_crt, - authorized_users, - } - ))) -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct CreateCARequest { - pub ip_ranges: Vec, - pub subnet_ranges: Vec, - pub groups: Vec -} - -#[post("/v1/org", data = "")] -pub async fn create_org(req: Json, user: TOTPAuthenticatedUserInfo, db: &State, config: &State) -> Result<(ContentType, Json), (Status, String)> { - if get_org_by_owner_id(user.user_id, db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))?.is_some() { - return Err((Status::Conflict, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_USER_OWNS_ORG", "a user can only own one organization at a time"))) - } - - // Generate the CA keypair - let private_key = SigningKey::generate(&mut OsRng); - let public_key = private_key.verifying_key(); - - // Create the CA certificate - let mut ca_cert = NebulaCertificate { - details: NebulaCertificateDetails { - name: format!("{}'s Organization - Root Signing CA", user.email), - ips: req.ip_ranges.clone(), - subnets: req.subnet_ranges.clone(), - groups: req.groups.clone(), - not_before: SystemTime::now(), - not_after: SystemTime::now() + Duration::from_secs(config.ca_certs_valid_for), - public_key: public_key.to_bytes(), - is_ca: true, - issuer: "".to_string(), // This is a self-signed certificate! There is no issuer present - }, - signature: vec![], - }; - // Self-sign the CA certificate - match ca_cert.sign(&private_key) { - Ok(_) => (), - Err(e) => { - error!("[tfapi] security: certificate signature error: {}", e); - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_CERT_SIGN_ERROR", "there was an error generating the CA certificate, please try again later"))) - } - } - - // PEM-encode the CA key - let ca_key_pem = serialize_ed25519_private(&private_key.to_keypair_bytes()); - // PEM-encode the CA cert - let ca_cert_pem = match ca_cert.serialize_to_pem() { - Ok(pem) => pem, - Err(e) => { - error!("[tfapi] security: certificate encoding error: {}", e); - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_CERT_ENCODE_ERROR", "there was an error encoding the CA certificate, please try again later"))) - } - }; - - // generate an AES iv to use for key encryption - let iv = generate_random_iv(); - let iv_hex = hex::encode(iv); - - let owner_id = user.user_id; - let cipher = match get_cipher_from_config(config) { - Ok(c) => c, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_CRYPTOGRAPHY_CREATE_CIPHER", "Unable to build cipher construct, please try again later", e))); - } - }; - let ca_key = match encrypt_with_nonce(&ca_key_pem, iv, &cipher) { - Ok(key) => hex::encode(key), - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_CRYPTOGRAPHY_ENCRYPT_KEY", "Unable to build cipher construct, please try again later", e))); - } - }; - let ca_crt = hex::encode(ca_cert_pem); - - let result = sqlx::query!("INSERT INTO organizations (owner, ca_key, ca_crt, iv) VALUES ($1, $2, $3, $4) RETURNING id", owner_id, ca_key, ca_crt, iv_hex).fetch_one(db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))?; - - // last step: create a default role to allow pings from all hosts - let role_id = match sqlx::query!("INSERT INTO roles (org, name, description) VALUES ($1, 'Default', 'Allow pings from other hosts. Default role for new hosts.') RETURNING id", result.id).fetch_one(db.inner()).await { - Ok(r) => r.id, - Err(e) => { - error!("[tfapi] dberror: {}", e); - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_INTERNAL_SERVER_ERROR", "Unable to create default role"))); - } - }; - - match sqlx::query!("INSERT INTO roles_firewall_rules (role, protocol, port_range_start, port_range_end, allow_from, description) VALUES ($1, 3, 1, 1, -1, 'Allow pings from anyone on the network')", role_id).execute(db.inner()).await { - Ok(_) => {}, - Err(e) => { - error!("[tfapi] dberror: {} inserting on roleid {}", e, role_id); - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_INTERNAL_SERVER_ERROR", "Unable to create default role firewall rules"))); - } - } - - Ok((ContentType::JSON, Json( - OrginfoStruct { - org_id: result.id, - owner_id, - ca_crt, - authorized_users: vec![owner_id], - } - ))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/roles.rs b/trifid-api/src/routes/v1/roles.rs deleted file mode 100644 index 538f65a..0000000 --- a/trifid-api/src/routes/v1/roles.rs +++ /dev/null @@ -1,95 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use log::error; -use rocket::{options, get, State, post}; -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; - -use serde::{Serialize, Deserialize}; -use sqlx::PgPool; -use crate::auth::TOTPAuthenticatedUserInfo; -use crate::org::user_has_org_assoc; -use crate::role::{get_role, get_role_ids_for_ca, Role}; - -#[options("/v1/org/<_org>/roles")] -pub fn options(_org: i32) -> &'static str { "" } -#[options("/v1/org/<_org>/role")] -pub fn options_roleadd(_org: i32) -> &'static str { "" } - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct RolesResponse { - pub data: Vec -} - -#[get("/v1/org//roles")] -pub async fn get_roles(org: i32, user: TOTPAuthenticatedUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { - if !user_has_org_assoc(user.user_id, org, db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))? { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_MISSING_ORG_AUTHORIZATION", "this user does not have permission to access this org"))); - } - - let roles = match get_role_ids_for_ca(org, db.inner()).await { - Ok(r) => r, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_INTERNAL_SERVER_ERR", "there was an error querying the db, please try again later", e))) - } - }; - - let mut resp = RolesResponse { - data: vec![] - }; - - for role in roles { - let role_info = match get_role(role, db.inner()).await { - Ok(r) => r, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_INTERNAL_SERVER_ERR", "there was an error querying the db, please try again later", e))) - } - }; - if let Some(info) = role_info { - resp.data.push(info); - } else { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_INTERNAL_SERVER_ERR", "there was an error querying the db, please try again later", "missing role as returned by server - possibly deleted inbetween?"))) - } - } - - Ok((ContentType::JSON, Json(resp))) -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct RoleaddReq { - pub name: String, - pub description: String -} - -#[post("/v1/org//role", data = "")] -pub async fn role_add(req: Json, org: i32, user: TOTPAuthenticatedUserInfo, db: &State) -> Result<(ContentType, String), (Status, String)> { - if !user_has_org_assoc(user.user_id, org, db.inner()).await.map_err(|e| (Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))? { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_MISSING_ORG_AUTHORIZATION", "this user does not have permission to access this org"))); - } - - match sqlx::query!("INSERT INTO roles (org, name, description) VALUES ($1, $2, $3)", org, req.name, req.description).execute(db.inner()).await { - Ok(_) => (), - Err(e) => { - error!("[tfapi] dberror: {}", e); - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_INTERNAL_SERVER_ERR", "database returned error while trying to create role", "unable to insert role"))) - } - } - - Ok((ContentType::JSON, "{}".to_string())) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/signup.rs b/trifid-api/src/routes/v1/signup.rs deleted file mode 100644 index be6a59f..0000000 --- a/trifid-api/src/routes/v1/signup.rs +++ /dev/null @@ -1,89 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::{post, State}; -use rocket::serde::json::Json; -use serde::{Serialize, Deserialize}; -use std::time::{SystemTime, UNIX_EPOCH}; -use rocket::http::{ContentType, Status}; -use sqlx::PgPool; -use crate::config::TFConfig; -use crate::tokens::send_magic_link; -use rocket::options; - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct SignupRequest { - pub email: String, -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct SignupResponseMetadata {} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct SignupResponse { - pub data: Option, - pub metadata: SignupResponseMetadata, -} -/* -created_on TIMESTAMP NOT NULL, - - banned INTEGER NOT NULL, - ban_reason VARCHAR(1024) NOT NULL - */ -#[options("/v1/signup")] -pub async fn options() -> &'static str { - "" -} - -#[post("/v1/signup", data = "")] -pub async fn signup_request(req: Json, pool: &State, config: &State) -> Result<(ContentType, Json), (Status, String)> { - // figure out if the user already exists - let mut id = -1; - match sqlx::query!("SELECT id FROM users WHERE email = $1", req.email.clone()).fetch_optional(pool.inner()).await { - Ok(res) => if let Some(r) = res { id = r.id as i64 }, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e))) - } - } - - if id == -1 { - let id_res = match sqlx::query!("INSERT INTO users (email, created_on, banned, ban_reason, totp_secret, totp_otpurl, totp_verified) VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT DO NOTHING RETURNING id;", req.email, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64, 0, "", "", "", 0).fetch_one(pool.inner()).await { - Ok(row) => row.id, - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e))) - } - }; - id = id_res as i64; - } - - // send magic link to email - match send_magic_link(id, req.email.clone(), pool.inner(), config.inner()).await { - Ok(_) => (), - Err(e) => { - return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e))) - } - }; - - // this endpoint doesn't actually ever return an error? it will send you the magic link no matter what - // this appears to do the exact same thing as /v1/auth/magic-link, but it doesn't check if you have an account (magic-link does) - Ok((ContentType::JSON, Json(SignupResponse { - data: None, - metadata: SignupResponseMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/totp_authenticators.rs b/trifid-api/src/routes/v1/totp_authenticators.rs deleted file mode 100644 index 55c4c92..0000000 --- a/trifid-api/src/routes/v1/totp_authenticators.rs +++ /dev/null @@ -1,76 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use rocket::{State, post}; -use sqlx::PgPool; -use serde::{Serialize, Deserialize}; -use crate::auth::PartialUserInfo; -use crate::config::TFConfig; -use crate::tokens::{create_totp_token, user_has_totp}; -use rocket::options; - -#[derive(Deserialize)] -pub struct TotpAuthenticatorsRequest {} -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpAuthenticatorsResponseMetadata {} -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpAuthenticatorsResponseData { - #[serde(rename = "totpToken")] - pub totp_token: String, - pub secret: String, - pub url: String, -} -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct TotpAuthenticatorsResponse { - pub data: TotpAuthenticatorsResponseData, - pub metadata: TotpAuthenticatorsResponseMetadata, -} - -#[options("/v1/totp-authenticators")] -pub async fn options() -> &'static str { - "" -} - - -#[post("/v1/totp-authenticators", data = "<_req>")] -pub async fn totp_authenticators_request(_req: Json, user: PartialUserInfo, db: &State, config: &State) -> Result<(ContentType, Json), (Status, String)> { - if match user_has_totp(user.user_id, db.inner()).await { - Ok(b) => b, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } { - return Err((Status::BadRequest, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", "ERR_TOTP_ALREADY_EXISTS", "this user already has a totp authenticator on their account"))) - } - - // generate a totp token - let (totptoken, totpmachine) = match create_totp_token(user.email, db.inner(), config.inner()).await { - Ok(t) => t, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured issuing a totp token, try again later", e))) - }; - - Ok((ContentType::JSON, Json(TotpAuthenticatorsResponse { - data: TotpAuthenticatorsResponseData { - totp_token: totptoken, - secret: totpmachine.get_secret_base32(), - url: totpmachine.get_url(), - }, - metadata: TotpAuthenticatorsResponseMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/user.rs b/trifid-api/src/routes/v1/user.rs deleted file mode 100644 index 99fe24e..0000000 --- a/trifid-api/src/routes/v1/user.rs +++ /dev/null @@ -1,47 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use serde::{Serialize, Deserialize}; -use rocket::{get, options}; -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use rocket::State; -use sqlx::PgPool; - -#[options("/v1/user/<_id>")] -pub fn options(_id: i32) -> &'static str { - "" -} - -#[derive(Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct UserInfoResponse { - email: String -} - -#[get("/v1/user/")] -pub async fn get_user(id: i32, db: &State) -> Result<(ContentType, Json), (Status, String)> { - let user = match sqlx::query!("SELECT email FROM users WHERE id = $1", id.clone() as i32).fetch_one(db.inner()).await { - Ok(u) => u, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e))) - }; - - Ok((ContentType::JSON, Json( - UserInfoResponse { - email: user.email, - } - ))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/verify_totp_authenticator.rs b/trifid-api/src/routes/v1/verify_totp_authenticator.rs deleted file mode 100644 index 223cffd..0000000 --- a/trifid-api/src/routes/v1/verify_totp_authenticator.rs +++ /dev/null @@ -1,75 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use rocket::http::{ContentType, Status}; -use crate::auth::PartialUserInfo; -use rocket::post; -use rocket::serde::json::Json; -use rocket::State; -use serde::{Serialize, Deserialize}; -use sqlx::PgPool; -use crate::tokens::{generate_auth_token, use_totp_token, verify_totp_token}; -use rocket::options; - -#[derive(Serialize, Deserialize)] -pub struct VerifyTotpAuthenticatorRequest { - #[serde(rename = "totpToken")] - pub totp_token: String, - pub code: String, -} - -#[derive(Serialize, Deserialize)] -pub struct VerifyTotpAuthenticatorResponseMetadata {} - -#[derive(Serialize, Deserialize)] -pub struct VerifyTotpAuthenticatorResponseData { - #[serde(rename = "authToken")] - pub auth_token: String, -} - -#[derive(Serialize, Deserialize)] -pub struct VerifyTotpAuthenticatorResponse { - pub data: VerifyTotpAuthenticatorResponseData, - pub metadata: VerifyTotpAuthenticatorResponseMetadata, -} - -#[options("/v1/verify-totp-authenticator")] -pub async fn options() -> &'static str { - "" -} - - -#[post("/v1/verify-totp-authenticator", data = "")] -pub async fn verify_totp_authenticator_request(req: Json, db: &State, user: PartialUserInfo) -> Result<(ContentType, Json), (Status, String)> { - let totpmachine = match verify_totp_token(req.0.totp_token.clone(), user.email.clone(), db.inner()).await { - Ok(t) => t, - Err(e) => return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNAUTHORIZED", "this token is invalid", e))) - }; - if !totpmachine.check_current(&req.0.code).unwrap() { - return Err((Status::Unauthorized, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\",\"path\":\"totpToken\"}}]}}", "ERR_INVALID_TOTP_CODE", "Invalid TOTP code"))) - } - match use_totp_token(req.0.totp_token, user.email, db.inner()).await { - Ok(_) => (), - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } - Ok((ContentType::JSON, Json(VerifyTotpAuthenticatorResponse { - data: VerifyTotpAuthenticatorResponseData { auth_token: match generate_auth_token(user.user_id as i64, user.session_id, db.inner()).await { - Ok(at) => at, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e))) - } }, - metadata: VerifyTotpAuthenticatorResponseMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/routes/v2/mod.rs b/trifid-api/src/routes/v2/mod.rs deleted file mode 100644 index c603733..0000000 --- a/trifid-api/src/routes/v2/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pub mod whoami; \ No newline at end of file diff --git a/trifid-api/src/routes/v2/whoami.rs b/trifid-api/src/routes/v2/whoami.rs deleted file mode 100644 index fcf87d7..0000000 --- a/trifid-api/src/routes/v2/whoami.rs +++ /dev/null @@ -1,85 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use chrono::{NaiveDateTime, Utc}; -use serde::{Serialize, Deserialize}; -use rocket::{options, get, State}; -use rocket::http::{ContentType, Status}; -use rocket::serde::json::Json; -use sqlx::PgPool; -use crate::auth::PartialUserInfo; -use crate::org::get_org_by_owner_id; -use crate::tokens::user_has_totp; - -#[derive(Serialize, Deserialize)] -pub struct WhoamiMetadata {} - -#[derive(Serialize, Deserialize)] -pub struct WhoamiActor { - pub id: String, - #[serde(rename = "organizationID")] - pub organization_id: String, - pub email: String, - #[serde(rename = "createdAt")] - pub created_at: String, - #[serde(rename = "hasTOTPAuthenticator")] - pub has_totpauthenticator: bool, -} - -#[derive(Serialize, Deserialize)] -pub struct WhoamiData { - #[serde(rename = "actorType")] - pub actor_type: String, - pub actor: WhoamiActor, -} - -#[derive(Serialize, Deserialize)] -pub struct WhoamiResponse { - pub data: WhoamiData, - pub metadata: WhoamiMetadata, -} - -#[options("/v2/whoami")] -pub fn options() -> &'static str { - "" -} - -#[get("/v2/whoami")] -pub async fn whoami_request(user: PartialUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { - let org = match get_org_by_owner_id(user.user_id, db.inner()).await { - Ok(b) => match b { - Some(r) => r.to_string(), - None => String::new() - }, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_DBERROR", "an error occured trying to verify your user", e))) - }; - Ok((ContentType::JSON, Json(WhoamiResponse { - data: WhoamiData { - actor_type: "user".to_string(), - actor: WhoamiActor { - id: user.user_id.to_string(), - organization_id: org, - email: user.email, - created_at: NaiveDateTime::from_timestamp_opt(user.created_at, 0).unwrap().and_local_timezone(Utc).unwrap().to_rfc3339(), - has_totpauthenticator: match user_has_totp(user.user_id, db.inner()).await { - Ok(b) => b, - Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_DBERROR", "an error occured trying to verify your user", e))) - }, - } - }, - metadata: WhoamiMetadata {}, - }))) -} \ No newline at end of file diff --git a/trifid-api/src/tokens.rs b/trifid-api/src/tokens.rs deleted file mode 100644 index 8590cdf..0000000 --- a/trifid-api/src/tokens.rs +++ /dev/null @@ -1,109 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use std::error::Error; -use log::info; -use sqlx::PgPool; -use uuid::Uuid; -use crate::config::TFConfig; -use std::time::SystemTime; -use std::time::UNIX_EPOCH; -use totp_rs::{Secret, TOTP}; -use crate::util::{TOTP_ALGORITHM, TOTP_DIGITS, TOTP_ISSUER, TOTP_SKEW, TOTP_STEP}; - -// https://admin.defined.net/auth/magic-link?email=coredoescode%40gmail.com&token=ml-ckBsgw_5IdK5VYgseBYcoV_v_cQjtdq1re_RhDu_MKg -pub async fn send_magic_link(id: i64, email: String, db: &PgPool, config: &TFConfig) -> Result<(), Box> { - let otp = format!("ml-{}", Uuid::new_v4()); - let otp_url = config.web_root.join(&format!("/auth/magic-link?email={}&token={}", urlencoding::encode(&email.clone()), otp.clone())).unwrap(); - sqlx::query!("INSERT INTO magic_links (id, user_id, expires_on) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING;", otp, id as i32, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32 + config.magic_links_valid_for as i32).execute(db).await?; - // TODO: send email - info!("sent magic link {} to {}, valid for {} seconds", otp_url, email.clone(), config.magic_links_valid_for); - Ok(()) -} - -pub async fn generate_session_token(user_id: i64, db: &PgPool, config: &TFConfig) -> Result> { - let token = format!("st-{}", Uuid::new_v4()); - sqlx::query!("INSERT INTO session_tokens (id, user_id, expires_on) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING;", token, user_id as i32, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32 + config.session_tokens_valid_for as i32).execute(db).await?; - Ok(token) -} -pub async fn validate_session_token(token: String, db: &PgPool) -> Result> { - Ok(sqlx::query!("SELECT user_id FROM session_tokens WHERE id = $1 AND expires_on > $2", token, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32).fetch_one(db).await?.user_id as i64) -} - -pub async fn generate_auth_token(user_id: i64, session_id: String, db: &PgPool) -> Result> { - let token = format!("at-{}", Uuid::new_v4()); - sqlx::query!("INSERT INTO auth_tokens (id, session_token, user_id) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING;", token, session_id, user_id as i32).execute(db).await?; - Ok(token) -} -pub async fn validate_auth_token(token: String, session_id: String, db: &PgPool) -> Result<(), Box> { - validate_session_token(session_id.clone(), db).await?; - sqlx::query!("SELECT * FROM auth_tokens WHERE id = $1 AND session_token = $2", token, session_id).fetch_one(db).await?; - Ok(()) -} - - -/* -CREATE TABLE totp_create_tokens ( - id VARCHAR(39) NOT NULL PRIMARY KEY, - expires_on INTEGER NOT NULL, - totp_otpurl VARCHAR(3000) NOT NULL, - totp_secret VARCHAR(128) NOT NULL -); - */ - -pub async fn create_totp_token(email: String, db: &PgPool, config: &TFConfig) -> Result<(String, TOTP), Box> { - // create the TOTP parameters - - let secret = Secret::generate_secret(); - let totpmachine = TOTP::new(TOTP_ALGORITHM, TOTP_DIGITS, TOTP_SKEW, TOTP_STEP, secret.to_bytes().unwrap(), Some(TOTP_ISSUER.to_string()), email).unwrap(); - let otpurl = totpmachine.get_url(); - let otpsecret = totpmachine.get_secret_base32(); - - let otpid = format!("totp-{}", Uuid::new_v4()); - - sqlx::query!("INSERT INTO totp_create_tokens (id, expires_on, totp_otpurl, totp_secret) VALUES ($1, $2, $3, $4);", otpid.clone(), (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + config.totp_verification_valid_for) as i32, otpurl, otpsecret).execute(db).await?; - - Ok((otpid, totpmachine)) -} - -pub async fn verify_totp_token(otpid: String, email: String, db: &PgPool) -> Result> { - let totprow = sqlx::query!("SELECT * FROM totp_create_tokens WHERE id = $1 AND expires_on > $2", otpid, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32).fetch_one(db).await?; - let secret = Secret::Encoded(totprow.totp_secret); - let totpmachine = TOTP::new(TOTP_ALGORITHM, TOTP_DIGITS, TOTP_SKEW, TOTP_STEP, secret.to_bytes().unwrap(), Some(TOTP_ISSUER.to_string()), email).unwrap(); - - if totpmachine.get_url() != totprow.totp_otpurl { - return Err("OTPURLs do not match (email does not match?)".into()) - } - - Ok(totpmachine) -} - -pub async fn use_totp_token(otpid: String, email: String, db: &PgPool) -> Result> { - let totpmachine = verify_totp_token(otpid.clone(), email.clone(), db).await?; - sqlx::query!("DELETE FROM totp_create_tokens WHERE id = $1", otpid).execute(db).await?; - sqlx::query!("UPDATE users SET totp_otpurl = $1, totp_secret = $2, totp_verified = 1 WHERE email = $3", totpmachine.get_url(), totpmachine.get_secret_base32(), email).execute(db).await?; - Ok(totpmachine) -} - -pub async fn get_totpmachine(user: i32, db: &PgPool) -> Result> { - let user = sqlx::query!("SELECT totp_secret, totp_otpurl, email FROM users WHERE id = $1", user).fetch_one(db).await?; - let secret = Secret::Encoded(user.totp_secret); - Ok(TOTP::new(TOTP_ALGORITHM, TOTP_DIGITS, TOTP_SKEW, TOTP_STEP, secret.to_bytes().unwrap(), Some(TOTP_ISSUER.to_string()), user.email).unwrap()) -} - -pub async fn user_has_totp(user: i32, db: &PgPool) -> Result> { - Ok(sqlx::query!("SELECT totp_verified FROM users WHERE id = $1", user).fetch_one(db).await?.totp_verified == 1) -} \ No newline at end of file diff --git a/trifid-api/src/util.rs b/trifid-api/src/util.rs deleted file mode 100644 index ca7857e..0000000 --- a/trifid-api/src/util.rs +++ /dev/null @@ -1,31 +0,0 @@ -// trifid-api, an open source reimplementation of the Defined Networking nebula management server. -// Copyright (C) 2023 c0repwn3r -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use base64::Engine; -use totp_rs::Algorithm; - -pub const TOTP_ALGORITHM: Algorithm = Algorithm::SHA1; -pub const TOTP_DIGITS: usize = 6; -pub const TOTP_SKEW: u8 = 1; -pub const TOTP_STEP: u64 = 30; -pub const TOTP_ISSUER: &str = "trifidapi"; - -pub fn base64decode(val: &str) -> Result, base64::DecodeError> { - base64::engine::general_purpose::STANDARD.decode(val) -} -pub fn base64encode(val: Vec) -> String { - base64::engine::general_purpose::STANDARD.encode(val) -} \ No newline at end of file