From 9fd1025d4a41f5842a142d5e8391addd34f76581 Mon Sep 17 00:00:00 2001 From: Andrey Tkachenko Date: Fri, 12 May 2023 13:07:05 +0400 Subject: [PATCH] schema update; error handling --- Cargo.lock | 488 +++++++++++++----- Cargo.toml | 3 + .../2023-05-11-145250_create_users/up.sql | 1 + src/api/error.rs | 37 +- src/api/mod.rs | 23 +- src/api/user.rs | 21 +- src/db/models/user.rs | 3 + src/db/repos/user.rs | 10 + src/db/schema.rs | 44 +- src/error.rs | 16 +- src/main.rs | 14 +- 11 files changed, 488 insertions(+), 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ddf7a3..5fd6f7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,54 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +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 0.13.1", + "bincode", + "blake3", + "chrono", + "hmac 0.11.0", + "log", + "rand", + "serde", + "serde_json", + "sha2 0.9.9", +] + [[package]] name = "async-trait" version = "0.1.68" @@ -39,6 +87,7 @@ dependencies = [ "bitflags", "bytes", "futures-util", + "headers", "http", "http-body", "hyper", @@ -79,18 +128,96 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-extra" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "febf23ab04509bd7672e6abe76bd8277af31b679e89fa5ffc6087dc289a448a3" +dependencies = [ + "axum", + "axum-core", + "bytes", + "cookie", + "futures-util", + "http", + "http-body", + "mime", + "pin-project-lite", + "serde", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-sessions" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714cad544cd87d8da821cda715bb9aaa5d4d1adbdb64c549b18138e3cbf93c44" +dependencies = [ + "async-session", + "axum", + "axum-extra", + "futures", + "http-body", + "tokio", + "tower", + "tracing", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[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]] name = "block-buffer" version = "0.10.4" @@ -124,6 +251,12 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +[[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" @@ -141,19 +274,31 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time", + "time 0.1.45", "wasm-bindgen", "winapi", ] [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "constant_time_eq" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ - "termcolor", - "unicode-width", + "base64 0.21.0", + "hmac 0.12.1", + "percent-encoding", + "rand", + "sha2 0.10.6", + "subtle", + "time 0.3.21", + "version_check", ] [[package]] @@ -182,10 +327,30 @@ dependencies = [ ] [[package]] -name = "ctxerr" -version = "0.2.5" +name = "crypto-mac" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82ec6dd79796c0cb5ac69ea5f2dd2e6143515539ad7b731587ebbd5efd27a1e" +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 = "ctxerr" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc30f239523a4f73a53f43566fd019f7dd471710369d811078b6fd0969c0878e" dependencies = [ "ctxerr_derive", "thiserror", @@ -193,53 +358,9 @@ dependencies = [ [[package]] name = "ctxerr_derive" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55030199475a2883992a841d8a84c4bf90d10b7297330e5bf81df50cd161390" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", -] - -[[package]] -name = "cxx" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.15", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +checksum = "5e9910bf975017d29a4d05d13911f58cc6d309e327ea9bf79a0a34533a41c1fc" dependencies = [ "proc-macro2", "quote", @@ -305,17 +426,32 @@ dependencies = [ "syn 1.0.109", ] +[[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.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", "subtle", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -442,7 +578,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] @@ -472,6 +608,31 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "headers" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +dependencies = [ + "base64 0.13.1", + "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 = "hermit-abi" version = "0.2.6" @@ -481,13 +642,29 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[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]] name = "hmac" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.6", ] [[package]] @@ -512,6 +689,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + [[package]] name = "httparse" version = "1.8.0" @@ -564,12 +747,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -602,29 +784,23 @@ name = "kttd" version = "0.1.0" dependencies = [ "axum", + "axum-sessions", "chrono", "ctxerr", "diesel", "diesel-async", + "rand", "serde", "serde_json", + "sha256", "tokio", ] [[package]] name = "libc" -version = "0.2.142" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "lock_api" @@ -642,7 +818,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]] @@ -657,7 +833,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "digest", + "digest 0.10.6", ] [[package]] @@ -719,6 +895,12 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[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.12.1" @@ -735,7 +917,7 @@ version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", @@ -804,15 +986,15 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" dependencies = [ - "base64", + "base64 0.21.0", "byteorder", "bytes", "fallible-iterator", - "hmac", + "hmac 0.12.1", "md-5", "memchr", "rand", - "sha2", + "sha2 0.10.6", "stringprep", ] @@ -868,9 +1050,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -938,7 +1120,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1473e24c637950c9bd38763220bea91ec3e095a89f672bbd7a10d03e77ba467" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "pin-utils", ] @@ -948,12 +1130,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "serde" version = "1.0.163" @@ -1006,15 +1182,49 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.6", +] + +[[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]] name = "sha2" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", - "digest", + "digest 0.10.6", +] + +[[package]] +name = "sha256" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f8b5de2bac3a4ae28e9b611072a8e326d9b26c8189c0972d4c321fa684f1f" +dependencies = [ + "hex", + "sha2 0.10.6", ] [[package]] @@ -1102,15 +1312,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.40" @@ -1142,6 +1343,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1159,9 +1387,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg", "bytes", @@ -1240,6 +1468,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.2" @@ -1254,20 +1500,33 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.38" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9cf6a813d3f40c88b0b6b6f29a5c95c6cdbf97c1f9cc53fb820200f5ad814d" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ + "cfg-if 1.0.0", "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] [[package]] -name = "tracing-core" -version = "0.1.30" +name = "tracing-attributes" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -1305,12 +1564,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "version_check" version = "0.9.4" @@ -1345,7 +1598,7 @@ version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -1409,15 +1662,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index ce967f2..4fd2c84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,13 @@ edition = "2021" [dependencies] axum = { version = "0.6.18", features = ["tracing", "http2"] } +axum-sessions = "0.5.0" chrono = { version = "0.4.24", features = ["serde"] } ctxerr = "0.2.5" diesel = { version = "2.0.4", features = ["chrono"] } diesel-async = { version = "0.2.2", features = ["postgres", "tokio-postgres", "deadpool"] } +rand = "0.8.5" serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.96" +sha256 = "1.1.3" tokio = { version = "1.28.0", features = ["parking_lot", "macros", "rt", "rt-multi-thread"] } diff --git a/migrations/2023-05-11-145250_create_users/up.sql b/migrations/2023-05-11-145250_create_users/up.sql index 4423369..c00d6a3 100644 --- a/migrations/2023-05-11-145250_create_users/up.sql +++ b/migrations/2023-05-11-145250_create_users/up.sql @@ -5,6 +5,7 @@ CREATE TABLE users ( first_name VARCHAR NOT NULL, last_name VARCHAR NOT NULL, email VARCHAR NOT NULL, + password VARCHAR(64) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL ) \ No newline at end of file diff --git a/src/api/error.rs b/src/api/error.rs index e4fd97c..6c9497d 100644 --- a/src/api/error.rs +++ b/src/api/error.rs @@ -9,21 +9,40 @@ use serde_json::json; #[ctxerr] pub enum ErrorKind { #[error("{0}")] - InternalError(#[from] crate::Error), + InternalError(crate::Error), + + #[error("Not Found")] + NotFound, +} + +impl From for ErrorKind { + fn from(v: crate::Error) -> Self { + match v.kind { + crate::ErrorKind::RecordNotFound(_) => Self::NotFound, + _ => Self::InternalError(v), + } + } } impl IntoResponse for Error { fn into_response(self) -> Response { let (status, error_message) = match self.kind { - ErrorKind::InternalError(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()), + ErrorKind::InternalError(err) => ( + StatusCode::INTERNAL_SERVER_ERROR, + json! ({ + "error": err.to_string(), + "location": self.location.map(ToString::to_string), + "backtrace": self.backtrace.map(|x|x.to_string()), + }), + ), + ErrorKind::NotFound => ( + StatusCode::NOT_FOUND, + json! ({ + "error": self.kind.to_string(), + }), + ), }; - ( - status, - Json(json! ({ - "error": error_message, - })), - ) - .into_response() + (status, Json(error_message)).into_response() } } diff --git a/src/api/mod.rs b/src/api/mod.rs index 39819b5..0abb281 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -6,6 +6,9 @@ use axum::{ Router, }; +use axum_sessions::{async_session::MemoryStore, SessionLayer}; +use rand::Rng; + use crate::db::DbPool; #[derive(Clone)] @@ -13,16 +16,22 @@ pub struct ApiState { pub pool: DbPool, } -pub async fn start_server(state: ApiState) { - // initialize tracing - // tracing_subscriber::fmt::init(); +pub async fn start_server(pool: DbPool) { + let mut secret = [0u8; 64]; + rand::thread_rng().fill(&mut secret); + + let session_store = MemoryStore::new(); + let session_layer = SessionLayer::new(session_store, &secret); + + let state = ApiState { pool }; - // build our application with a route let app = Router::new() .route("/", get(root)) - .route("/users", post(user::create_user)) - .route("/users", get(user::list_user)) - .with_state(state); + .route("/user", post(user::create_user)) + .route("/user/list", get(user::list_users)) + .route("/user/:id", get(user::get_user)) + .with_state(state) + .layer(session_layer); axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service()) diff --git a/src/api/user.rs b/src/api/user.rs index 68044c8..9ff2ee5 100644 --- a/src/api/user.rs +++ b/src/api/user.rs @@ -1,4 +1,8 @@ -use axum::{extract::State, http::StatusCode, Json}; +use axum::{ + extract::{Path, State}, + http::StatusCode, + Json, +}; use serde::Deserialize; use crate::db::{ @@ -13,6 +17,7 @@ pub struct ApiUser { first_name: String, last_name: String, email: String, + password: String, } pub async fn create_user( @@ -25,6 +30,7 @@ pub async fn create_user( first_name: &payload.first_name, last_name: &payload.last_name, email: &payload.email, + password: &sha256::digest(payload.password), }, ) .await?; @@ -32,8 +38,13 @@ pub async fn create_user( Ok((StatusCode::CREATED, Json(user))) } -pub async fn list_user(State(s): State) -> (StatusCode, Json>) { - let user = repos::user::list_users(&s.pool).await.unwrap(); - - (StatusCode::CREATED, Json(user)) +pub async fn list_users(State(s): State) -> Result>, Error> { + Ok(Json(repos::user::list_users(&s.pool).await?)) +} + +pub async fn get_user( + State(s): State, + Path(user_id): Path, +) -> Result, Error> { + Ok(Json(repos::user::fetch_user(&s.pool, user_id).await?)) } diff --git a/src/db/models/user.rs b/src/db/models/user.rs index 4885027..888d19a 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -11,6 +11,8 @@ pub struct User { pub first_name: String, pub last_name: String, pub email: String, + #[serde(skip)] + pub password: String, pub created_at: chrono::NaiveDateTime, pub updated_at: chrono::NaiveDateTime, } @@ -21,4 +23,5 @@ pub struct NewUser<'a> { pub first_name: &'a str, pub last_name: &'a str, pub email: &'a str, + pub password: &'a str, } diff --git a/src/db/repos/user.rs b/src/db/repos/user.rs index 0edeb8b..c6272ff 100644 --- a/src/db/repos/user.rs +++ b/src/db/repos/user.rs @@ -23,3 +23,13 @@ pub async fn list_users(pool: &DbPool) -> Result, Error> { .load(&mut conn) .await?) } + +pub async fn fetch_user(pool: &DbPool, user_id: i32) -> Result { + let mut conn = pool.get().await?; + + Ok(users::table + .filter(users::id.eq(user_id)) + .select(User::as_select()) + .first(&mut conn) + .await?) +} diff --git a/src/db/schema.rs b/src/db/schema.rs index cabbdf1..72276ca 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -5,6 +5,7 @@ diesel::table! { first_name -> VarChar, last_name -> VarChar, email -> VarChar, + password -> VarChar, created_at -> Timestamp, updated_at -> Timestamp, } @@ -20,7 +21,22 @@ diesel::table! { } diesel::table! { - items { + user_session { + id -> Int4, + user_id -> Int4, + title -> VarChar, + active -> Bool, + device_kind -> Nullable, + device_os -> Nullable, + device_browser -> Nullable, + description -> Nullable, + last_access -> Timestamp, + created_at -> Timestamp, + } +} + +diesel::table! { + subjects { id -> Int4, title -> VarChar, image_id -> Nullable, @@ -43,15 +59,15 @@ diesel::table! { } diesel::table! { - item_image { + subject_image { id -> Int4, - item_id -> Int4, + subject_id -> Int4, image_id -> Int4, } } diesel::table! { - locations { + taxonomies { id -> Int4, parent_id -> Nullable, image_id -> Nullable, @@ -64,9 +80,9 @@ diesel::table! { } diesel::table! { - location_image { + taxonomy_image { id -> Int4, - location_id -> Int4, + taxonomy_id -> Int4, image_id -> Int4, } } @@ -89,20 +105,20 @@ diesel::table! { } diesel::table! { - item_task { + subject_task { id -> Int4, - location_id -> Int4, + taxonomy_id -> Int4, image_id -> Int4, } } diesel::joinable!(users -> images (image_id)); -diesel::joinable!(item_image -> images (image_id)); -diesel::joinable!(item_image -> items (item_id)); +diesel::joinable!(subject_image -> images (image_id)); +diesel::joinable!(subject_image -> subjects (subject_id)); -diesel::joinable!(location_image -> images (image_id)); -diesel::joinable!(location_image -> locations (location_id)); +diesel::joinable!(taxonomy_image -> images (image_id)); +diesel::joinable!(taxonomy_image -> taxonomies (taxonomy_id)); -diesel::allow_tables_to_appear_in_same_query!(items, item_image, images,); -diesel::allow_tables_to_appear_in_same_query!(items, location_image, locations,); +diesel::allow_tables_to_appear_in_same_query!(subjects, subject_image, images,); +diesel::allow_tables_to_appear_in_same_query!(subjects, taxonomy_image, taxonomies,); diff --git a/src/error.rs b/src/error.rs index a13a7c3..78ebd33 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,6 +11,18 @@ pub enum ErrorKind { #[error("PoolBuildError: {0}")] PoolBuild(#[from] BuildError), - #[error("DieselResultError: {0}")] - DieselResult(#[from] result::Error), + #[error("DieselError: {0}")] + DieselResult(result::Error), + + #[error("RecordNotFound: {0}")] + RecordNotFound(result::Error), +} + +impl From for ErrorKind { + fn from(v: result::Error) -> Self { + match v { + res @ result::Error::NotFound => Self::RecordNotFound(res), + other => Self::DieselResult(other), + } + } } diff --git a/src/main.rs b/src/main.rs index 71a7655..75e5f1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,19 +9,7 @@ async fn main() -> Result<(), Error> { let durl = std::env::var("DATABASE_URL") .unwrap_or_else(|_| "postgres://postgres@127.0.0.1:5432/kttd".to_string()); - let pool = db::connect(durl).await?; - - // repos::user::create_user( - // &pool, - // db::models::user::NewUser { - // first_name: "Andrey", - // last_name: "Tkachenko", - // email: "andrey@aidev.ru", - // }, - // ) - // .await?; - - api::start_server(api::ApiState { pool }).await; + api::start_server(db::connect(durl).await?).await; Ok(()) }