diff --git a/Cargo.lock b/Cargo.lock index e33c215..704b111 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,41 @@ 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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" +dependencies = [ + "cfg-if 1.0.0", + "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" @@ -53,6 +88,15 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -79,6 +123,18 @@ dependencies = [ "password-hash", ] +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "ascii_utils" version = "0.9.3" @@ -129,6 +185,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "async-graphql-axum" +version = "4.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a55a393b11b95d952a8f6614c9db55e1875138c364ec34ca40b38e15c7ee71" +dependencies = [ + "async-graphql", + "async-trait", + "axum", + "bytes", + "futures-util", + "http-body", + "serde_json", + "serde_urlencoded", + "tokio-util", + "tower-service", +] + [[package]] name = "async-graphql-derive" version = "4.0.6" @@ -169,6 +243,36 @@ dependencies = [ "serde_json", ] +[[package]] +name = "async-lock" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-session" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da4ce523b4e2ebaaf330746761df23a465b951a83d84bbce4233dabedae630" +dependencies = [ + "anyhow", + "async-lock", + "async-trait", + "base64", + "bincode", + "blake3", + "chrono", + "hmac 0.11.0", + "log", + "rand", + "serde", + "serde_json", + "sha2 0.9.9", +] + [[package]] name = "async-stream" version = "0.3.3" @@ -224,9 +328,11 @@ checksum = "9de18bc5f2e9df8f52da03856bf40e29b747de5a84e43aefff90e3dc4a21529b" dependencies = [ "async-trait", "axum-core", + "base64", "bitflags", "bytes", "futures-util", + "headers", "http", "http-body", "hyper", @@ -239,8 +345,10 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sha-1", "sync_wrapper", "tokio", + "tokio-tungstenite", "tower", "tower-http", "tower-layer", @@ -261,6 +369,42 @@ dependencies = [ "mime", ] +[[package]] +name = "axum-extra" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69034b3b0fd97923eee2ce8a47540edb21e07f48f87f67d44bb4271cec622bdb" +dependencies = [ + "axum", + "bytes", + "cookie", + "futures-util", + "http", + "mime", + "pin-project-lite", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-sessions" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edac5a983d2aa76c3764a3e0a59e5fa885f5af468de4e4ce2f9182223cf281c" +dependencies = [ + "async-session", + "axum", + "axum-extra", + "futures", + "http-body", + "tokio", + "tower", + "tracing", +] + [[package]] name = "base64" version = "0.13.0" @@ -273,6 +417,15 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -285,7 +438,31 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" dependencies = [ - "digest", + "digest 0.10.3", +] + +[[package]] +name = "blake3" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 0.1.10", + "constant_time_eq", + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", ] [[package]] @@ -345,6 +522,12 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -352,16 +535,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "como_bin" +name = "chrono" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "serde", + "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 = "como_bff" version = "0.1.0" dependencies = [ "anyhow", - "argon2", - "async-graphql", "axum", - "cookie", + "axum-extra", + "axum-sessions", "dotenv", - "rand_core", "sqlx", "tokio", "tower-http", @@ -370,16 +574,60 @@ dependencies = [ "uuid", ] +[[package]] +name = "como_bin" +version = "0.1.0" +dependencies = [ + "anyhow", + "argon2", + "async-graphql", + "async-graphql-axum", + "axum", + "axum-extra", + "axum-sessions", + "cookie", + "dotenv", + "rand_core", + "serde", + "serde_json", + "sqlx", + "tokio", + "tower-http", + "tracing", + "tracing-subscriber", + "uuid", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "cookie" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" dependencies = [ + "aes-gcm", + "base64", + "hkdf", + "hmac 0.12.1", + "percent-encoding", + "rand", + "sha2 0.10.2", + "subtle", "time", "version_check", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + [[package]] name = "cpufeatures" version = "0.2.2" @@ -410,7 +658,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -419,7 +667,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -429,7 +677,7 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "once_cell", ] @@ -440,9 +688,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "darling" version = "0.14.1" @@ -478,13 +756,22 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer", + "block-buffer 0.10.2", "crypto-common", "subtle", ] @@ -539,7 +826,7 @@ version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -593,10 +880,25 @@ dependencies = [ ] [[package]] -name = "futures-channel" -version = "0.3.21" +name = "futures" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", "futures-sink", @@ -604,9 +906,20 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" + +[[package]] +name = "futures-executor" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] [[package]] name = "futures-intrusive" @@ -621,30 +934,43 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" + +[[package]] +name = "futures-macro" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -669,11 +995,21 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "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 = "hashbrown" version = "0.12.3" @@ -692,6 +1028,31 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "headers" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + [[package]] name = "heck" version = "0.4.0" @@ -722,7 +1083,17 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", ] [[package]] @@ -731,7 +1102,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.3", ] [[package]] @@ -797,6 +1168,19 @@ dependencies = [ "want", ] +[[package]] +name = "iana-time-zone" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "js-sys", + "wasm-bindgen", + "winapi", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -825,13 +1209,22 @@ dependencies = [ "serde", ] +[[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", + "cfg-if 1.0.0", ] [[package]] @@ -895,7 +1288,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -925,7 +1318,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582" dependencies = [ - "digest", + "digest 0.10.3", ] [[package]] @@ -1005,6 +1398,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1039,6 +1442,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "parking_lot" version = "0.11.2" @@ -1066,7 +1475,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "instant", "libc", "redox_syscall", @@ -1080,7 +1489,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", @@ -1152,6 +1561,18 @@ 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 1.0.0", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -1379,9 +1800,33 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", - "digest", + "digest 0.10.3", +] + +[[package]] +name = "sha1" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.3", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -1390,9 +1835,9 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", - "digest", + "digest 0.10.3", ] [[package]] @@ -1496,7 +1941,7 @@ dependencies = [ "hashlink", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "indexmap", "itoa", "libc", @@ -1512,7 +1957,7 @@ dependencies = [ "serde", "serde_json", "sha-1", - "sha2", + "sha2 0.10.2", "smallvec", "sqlformat", "sqlx-rt", @@ -1540,7 +1985,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.2", "sqlx-core", "sqlx-rt", "syn", @@ -1609,7 +2054,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "libc", "redox_syscall", @@ -1733,6 +2178,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.3" @@ -1741,6 +2198,7 @@ checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -1819,7 +2277,7 @@ version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "log", "pin-project-lite", "tracing-attributes", @@ -1882,6 +2340,25 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "sha-1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.15.0" @@ -1936,6 +2413,16 @@ 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 = "untrusted" version = "0.7.1" @@ -1954,6 +2441,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "uuid" version = "1.1.2" @@ -1998,7 +2491,7 @@ version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] diff --git a/Cargo.toml b/Cargo.toml index 0279b1b..843f87c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,2 @@ [workspace] -members = [ - "como_bin" -] +members = ["como_bin", "como_bff"] diff --git a/como_bff/Cargo.toml b/como_bff/Cargo.toml new file mode 100644 index 0000000..23d500f --- /dev/null +++ b/como_bff/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "como_bff" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum = "0.5.13" +axum-extra = { version = "*", features = ["cookie", "cookie-private"] } +axum-sessions = { version = "*" } +tokio = { version = "1.20.1", features = ["full"] } +uuid = { version = "1.1.2", features = ["v4", "fast-rng"] } +sqlx = { version = "0.6", features = [ + "runtime-tokio-rustls", + "postgres", + "migrate", + "uuid", + "offline", +] } +anyhow = "1.0.60" +dotenv = "0.15.0" +tracing = "0.1.36" +tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } +tower-http = { version = "0.3.4", features = ["full"] } diff --git a/como_bff/README.md b/como_bff/README.md new file mode 100644 index 0000000..0db1098 --- /dev/null +++ b/como_bff/README.md @@ -0,0 +1,21 @@ +# Como BFF + +```mermaid +sequenceDiagram + client ->> bff: request /events + bff ->> bff: Validates cookie como.sid + bff ->> bff: Cookie does not exist + bff ->> client: 401 + client ->> bff: Redirect /login + bff ->> auth: /login + auth ->> client: show webpage (give options) + client ->> auth: Submit credentials + auth ->> auth: Produce JWT + auth ->> bff: redirect with jwt/refreshtoken + bff ->> bff: wrap in cookie + bff ->> client: Redirect with cookie + client ->> bff: request /events + bff ->> events: forward request + events --> bff: returns events + bff --> client: return events +``` diff --git a/como_bff/src/main.rs b/como_bff/src/main.rs new file mode 100644 index 0000000..327b666 --- /dev/null +++ b/como_bff/src/main.rs @@ -0,0 +1,82 @@ +use std::env::{self, current_dir}; + +use async_graphql_axum::{GraphQLRequest, GraphQLResponse}; +use axum::{ + extract::Extension, + http::{Method, StatusCode}, + response::{Html, IntoResponse}, + routing::{get, post}, + Json, Router, +}; +use axum_extra::extract::{cookie::Key, PrivateCookieJar}; + +use async_graphql::{ + http::{playground_source, GraphQLPlaygroundConfig}, + EmptySubscription, Request, Response, Schema, +}; +use axum_sessions::{ + async_session::MemoryStore, + extractors::{ReadableSession, WritableSession}, + SessionLayer, +}; +use error::AppError; +use graphql::CibusSchema; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use services::users_service; +use sqlx::PgPool; +use tower_http::{cors::CorsLayer, trace::TraceLayer}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + +use crate::graphql::{MutationRoot, QueryRoot}; +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Environment + tracing::info!("Loading dotenv"); + dotenv::dotenv()?; + + // Logging + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::new( + std::env::var("RUST_LOG").unwrap_or_else(|_| { + "como_bin=debug,tower_http=debug,axum_extra=debug,hyper=info,mio=info,sqlx=info,async_graphql=debug" + .into() + }), + )) + .with(tracing_subscriber::fmt::layer()) + .init(); + + // Database + tracing::info!("Creating pool"); + let db_url = env::var("DATABASE_URL")?; + let pool = PgPool::connect(&db_url).await?; + + // Database Migrate + tracing::info!("Migrating db"); + sqlx::migrate!("db/migrations").run(&pool).await?; + + tracing::info!("current path: {}", current_dir()?.to_string_lossy()); + + // CORS + let cors = vec!["http://localhost:3000".parse().unwrap()]; + + // Webserver + tracing::info!("Building router"); + let app = Router::new() + .layer(TraceLayer::new_for_http()) + .layer(Extension(pool)) + .layer( + CorsLayer::new() + .allow_origin(cors) + .allow_headers([axum::http::header::CONTENT_TYPE]) + .allow_methods([Method::GET, Method::POST, Method::OPTIONS]), + ); + + tracing::info!("Starting webserver"); + axum::Server::bind(&"0.0.0.0:3002".parse().unwrap()) + .serve(app.into_make_service()) + .await + .unwrap(); + + Ok(()) +} diff --git a/como_bin/Cargo.toml b/como_bin/Cargo.toml index 6cbb2d4..ccc41cd 100644 --- a/como_bin/Cargo.toml +++ b/como_bin/Cargo.toml @@ -7,7 +7,12 @@ edition = "2021" [dependencies] async-graphql = "4.0.6" +async-graphql-axum = "*" axum = "0.5.13" +axum-extra = { version = "*", features = ["cookie", "cookie-private"] } +axum-sessions = { version = "*" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.68" tokio = { version = "1.20.1", features = ["full"] } uuid = { version = "1.1.2", features = ["v4", "fast-rng"] } sqlx = { version = "0.6", features = [ @@ -24,4 +29,4 @@ tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } tower-http = { version = "0.3.4", features = ["full"] } argon2 = "0.4" rand_core = { version = "0.6", features = ["std"] } -cookie = "0.16" +cookie = { version = "0.16", features = ["secure", "percent-encode"] } diff --git a/como_bin/src/error.rs b/como_bin/src/error.rs new file mode 100644 index 0000000..bc8201a --- /dev/null +++ b/como_bin/src/error.rs @@ -0,0 +1,21 @@ +use axum::{http::StatusCode, response::IntoResponse, Json}; +use serde_json::json; + +#[derive(Debug)] +pub enum AppError { + WrongCredentials, + InternalServerError, +} + +impl IntoResponse for AppError { + fn into_response(self) -> axum::response::Response { + let (status, err_msg) = match self { + Self::WrongCredentials => (StatusCode::BAD_REQUEST, "invalid credentials"), + Self::InternalServerError => ( + StatusCode::INTERNAL_SERVER_ERROR, + "something went wrong with your request", + ), + }; + (status, Json(json!({ "error": err_msg }))).into_response() + } +} diff --git a/como_bin/src/graphql.rs b/como_bin/src/graphql.rs index 1198d25..6c1ced2 100644 --- a/como_bin/src/graphql.rs +++ b/como_bin/src/graphql.rs @@ -1,4 +1,6 @@ use async_graphql::{Context, EmptySubscription, Object, Schema, SimpleObject}; +use axum_extra::extract::PrivateCookieJar; +use cookie::CookieJar; use uuid::Uuid; use crate::services::users_service::UserService; @@ -18,11 +20,12 @@ impl MutationRoot { let user_service = ctx.data_unchecked::(); let valid = user_service.validate_user(username, password).await?; - - Ok(match valid { + let returnvalid = match valid { Some(..) => true, None => false, - }) + }; + + Ok(returnvalid) } async fn register( diff --git a/como_bin/src/main.rs b/como_bin/src/main.rs index 1a59b46..54031c2 100644 --- a/como_bin/src/main.rs +++ b/como_bin/src/main.rs @@ -1,22 +1,33 @@ use std::env::{self, current_dir}; +mod error; mod gqlx; mod graphql; mod services; +use async_graphql_axum::{GraphQLRequest, GraphQLResponse}; use axum::{ extract::Extension, - http::Method, + http::{Method, StatusCode}, response::{Html, IntoResponse}, - routing::get, + routing::{get, post}, Json, Router, }; +use axum_extra::extract::{cookie::Key, PrivateCookieJar}; use async_graphql::{ http::{playground_source, GraphQLPlaygroundConfig}, EmptySubscription, Request, Response, Schema, }; +use axum_sessions::{ + async_session::MemoryStore, + extractors::{ReadableSession, WritableSession}, + SessionLayer, +}; +use error::AppError; use graphql::CibusSchema; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; use services::users_service; use sqlx::PgPool; use tower_http::{cors::CorsLayer, trace::TraceLayer}; @@ -24,8 +35,22 @@ use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use crate::graphql::{MutationRoot, QueryRoot}; -async fn graphql_handler(schema: Extension, req: Json) -> Json { - schema.execute(req.0).await.into() +async fn graphql_handler( + schema: Extension, + session: ReadableSession, + req: GraphQLRequest, +) -> Result { + let mut req = req.into_inner(); + if let Some(user_id) = session.get::("userId") { + req = req.data(user_id); + return Ok(schema.execute(req).await.into()); + } else if let Some(on) = &req.operation_name { + if on == "IntrospectionQuery" { + return Ok(schema.execute(req).await.into()); + } + } + + Err(StatusCode::FORBIDDEN) } async fn graphql_playground() -> impl IntoResponse { @@ -63,18 +88,29 @@ async fn main() -> anyhow::Result<()> { // Schema println!("Building schema"); let schema = Schema::build(QueryRoot, MutationRoot, EmptySubscription) - .data(users_service::UserService::new(pool)) + .data(users_service::UserService::new(pool.clone())) .finish(); // CORS let cors = vec!["http://localhost:3000".parse().unwrap()]; + // Key + let key = Key::generate(); + + let store = MemoryStore::new(); + let session_layer = SessionLayer::new(store, key.master()); + // Webserver tracing::info!("Building router"); let app = Router::new() .route("/", get(graphql_playground).post(graphql_handler)) - .layer(Extension(schema)) + .route("/auth/login", post(login)) + .route("/auth/register", post(register)) .layer(TraceLayer::new_for_http()) + .layer(Extension(schema)) + .layer(Extension(key)) + .layer(Extension(pool)) + .layer(session_layer) .layer( CorsLayer::new() .allow_origin(cors) @@ -90,3 +126,50 @@ async fn main() -> anyhow::Result<()> { Ok(()) } + +#[derive(Serialize, Deserialize)] +pub struct Credentials { + pub username: String, + pub password: String, +} + +async fn login( + Json(credentials): Json, + Extension(pool): Extension, + mut session: WritableSession, +) -> Result, error::AppError> { + let us = users_service::UserService::new(pool); + match us + .validate_user(credentials.username, credentials.password) + .await + .map_err(|e| { + tracing::error!("could not validate user: {}", e); + + AppError::InternalServerError + })? { + Some(user_id) => { + if let Err(e) = session.insert("userId", user_id.clone()) { + tracing::error!("could not insert session: {}", e); + return Err(AppError::InternalServerError); + } + + Ok(Json(json!({ "userId": user_id }))) + } + None => Err(AppError::WrongCredentials), + } +} +async fn register( + Json(credentials): Json, + Extension(pool): Extension, +) -> Result, error::AppError> { + let us = users_service::UserService::new(pool) + .add_user(credentials.username, credentials.password) + .await + .map_err(|e| { + tracing::error!("could not add user: {}", e); + + AppError::InternalServerError + })?; + + Ok(Json(json!({ "userId": us }))) +} diff --git a/como_bin/src/services/cookie_service.rs b/como_bin/src/services/cookie_service.rs deleted file mode 100644 index c0d64c6..0000000 --- a/como_bin/src/services/cookie_service.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct CookieService {} diff --git a/como_bin/src/services/mod.rs b/como_bin/src/services/mod.rs index 793e34e..433996f 100644 --- a/como_bin/src/services/mod.rs +++ b/como_bin/src/services/mod.rs @@ -1,2 +1 @@ -pub mod cookie_service; pub mod users_service; diff --git a/como_bin/src/services/users_service.rs b/como_bin/src/services/users_service.rs index ab01764..f0bf1e7 100644 --- a/como_bin/src/services/users_service.rs +++ b/como_bin/src/services/users_service.rs @@ -1,5 +1,3 @@ - - use anyhow::anyhow; use argon2::{password_hash::SaltString, Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; use rand_core::OsRng; @@ -36,7 +34,7 @@ impl UserService { &self, username: String, password: String, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let rec = sqlx::query!( r#" SELECT * from users @@ -49,7 +47,7 @@ impl UserService { match rec { Some(user) => match self.validate_password(password, user.password_hash)? { - true => Ok(Some(())), + true => Ok(Some(user.id.to_string())), false => Ok(None), }, None => Ok(None), diff --git a/como_bin/target/sqlx/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json b/como_bin/target/sqlx/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json new file mode 100644 index 0000000..c881b13 --- /dev/null +++ b/como_bin/target/sqlx/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json @@ -0,0 +1,33 @@ +{ + "query": "\n SELECT * from users\n where username=$1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "username", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "password_hash", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "d3f222cf6c3d9816705426fdbed3b13cb575bb432eb1f33676c0b414e67aecaf" +} \ No newline at end of file