diff --git a/Cargo.lock b/Cargo.lock index cbfb905..9f75adf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "async-attributes" @@ -29,9 +29,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" dependencies = [ "concurrent-queue", "event-listener", @@ -40,23 +40,23 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" dependencies = [ + "async-lock", "async-task", "concurrent-queue", "fastrand", "futures-lite", - "once_cell", "slab", ] [[package]] name = "async-global-executor" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da5b41ee986eed3f524c380e6d64965aea573882a8907682ad100f7859305ca" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" dependencies = [ "async-channel", "async-executor", @@ -69,31 +69,32 @@ dependencies = [ [[package]] name = "async-io" -version = "1.9.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" dependencies = [ + "async-lock", "autocfg", "concurrent-queue", "futures-lite", "libc", "log", - "once_cell", "parking", "polling", "slab", "socket2", "waker-fn", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "async-lock" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" dependencies = [ "event-listener", + "futures-lite", ] [[package]] @@ -131,9 +132,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" dependencies = [ "proc-macro2", "quote", @@ -142,9 +143,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" [[package]] name = "atty" @@ -152,7 +153,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -177,9 +178,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64ct" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "binstring" @@ -204,23 +205,23 @@ dependencies = [ [[package]] name = "blocking" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" dependencies = [ "async-channel", + "async-lock", "async-task", "atomic-waker", "fastrand", "futures-lite", - "once_cell", ] [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byteorder" @@ -230,21 +231,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -254,9 +249,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.22" +version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", "bitflags", @@ -316,11 +311,11 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "1.2.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" dependencies = [ - "cache-padded", + "crossbeam-utils", ] [[package]] @@ -334,15 +329,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "const-oid" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] name = "cpufeatures" @@ -355,23 +344,13 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -402,9 +381,9 @@ checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" [[package]] name = "ctor" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", "syn", @@ -412,54 +391,44 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.7.1", - "crypto-bigint 0.3.2", - "pem-rfc7468 0.3.1", -] - -[[package]] -name = "der" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" -dependencies = [ - "const-oid 0.9.0", - "pem-rfc7468 0.6.0", + "const-oid", + "pem-rfc7468", "zeroize", ] [[package]] name = "digest" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "12844141594ad74185a926d030f3b605f6a903b4e3fec351f3ea338ac5b7637e" dependencies = [ - "der 0.6.0", + "der", "elliptic-curve", "rfc6979", - "signature", + "signature 2.0.0", ] [[package]] name = "ed25519-compact" -version = "1.0.16" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18997d4604542d0736fae2c5ad6de987f0a50530cbcc14a7ce5a685328a252d" +checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c" dependencies = [ "ct-codecs", "getrandom", @@ -472,15 +441,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", - "crypto-bigint 0.4.9", - "der 0.6.0", + "crypto-bigint", + "der", "digest", "ff", "generic-array", "group", "hkdf", - "pem-rfc7468 0.6.0", - "pkcs8 0.9.0", + "pem-rfc7468", + "pkcs8", "rand_core", "sec1", "subtle", @@ -495,18 +464,18 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "ff" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core", "subtle", @@ -514,24 +483,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-lite" @@ -560,9 +529,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -571,9 +540,9 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ "futures-channel", "futures-core", @@ -583,9 +552,9 @@ dependencies = [ [[package]] name = "group" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core", @@ -600,9 +569,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -613,6 +582,15 @@ 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" @@ -633,33 +611,44 @@ dependencies = [ [[package]] name = "hmac-sha1-compact" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d103cfecf6edf3f7d1dc7c5ab64e99488c0f8d11786e43b40873e66e8489d014" +checksum = "05e2440a0078e20c3b68ca01234cea4219f23e64b0c0bdb1200c5550d54239bb" [[package]] name = "hmac-sha256" -version = "1.1.4" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd29dbba58ee5314f3ec570066d78a3f4772bf45b322efcf2ce2a43af69a4d85" +checksum = "fc736091aacb31ddaa4cd5f6988b3c21e99913ac846b41f32538c5fae5d71bfe" dependencies = [ "digest", ] [[package]] name = "hmac-sha512" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a928b002dff1780b7fa21056991d395770ab9359154b8c1724c4d0511dad0a65" +checksum = "520c9c3f6040661669bc5c91e551b605a520c8e0a63a766a91a65adef734d151" dependencies = [ "digest", ] +[[package]] +name = "http" +version = "0.1.6" +source = "git+https://gitea.thegux.fr/rmanach/http#0e616570907f3427be99f4bfc227bd57a252c8c1" +dependencies = [ + "json", + "lazy_static", + "log", + "regex", +] + [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -676,15 +665,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -697,9 +686,9 @@ checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] name = "jwt-simple" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7fe9aa2d76d0ec88af6f9c993dc369ab3a2773ffef50916dfc7453e875f336a" +checksum = "21a4c8e544a27e20e2fe4b82a93a9e823f01ebcc1e4e135e839db66df0e7dc54" dependencies = [ "anyhow", "binstring", @@ -716,21 +705,23 @@ dependencies = [ "rsa", "serde", "serde_json", - "spki 0.5.4", + "spki", "thiserror", "zeroize", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "92a55e0ff3b72c262bcf041d9e97f1b84492b68f1c1a384de2323d3dc9403397" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", + "once_cell", "sha2", + "signature 2.0.0", ] [[package]] @@ -753,15 +744,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.135" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libm" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "lock_api" @@ -791,21 +782,21 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mio" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.36.1", + "windows-sys 0.45.0", ] [[package]] name = "num-bigint-dig" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566d173b2f9406afbc5510a90925d5a2cd80cae4605631f1212303df265de011" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" dependencies = [ "byteorder", "lazy_static", @@ -851,11 +842,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -870,35 +861,37 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.15.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "os_str_bytes" -version = "6.3.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "p256" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +checksum = "49c124b3cbce43bcbac68c58ec181d98ed6cc7e6d0aa7c3ba97b2563410b0e55" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2", ] [[package]] name = "p384" -version = "0.11.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +checksum = "630a4a9b2618348ececfae61a4905f564b817063bf2d66cdfc2ced523fe1d2d4" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2", ] @@ -920,24 +913,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.36.1", -] - -[[package]] -name = "pem-rfc7468" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" -dependencies = [ - "base64ct", + "windows-sys 0.45.0", ] [[package]] @@ -963,23 +947,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" dependencies = [ - "der 0.5.1", - "pkcs8 0.8.0", - "zeroize", -] - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der 0.5.1", - "spki 0.5.4", + "der", + "pkcs8", + "spki", "zeroize", ] @@ -989,29 +963,38 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der 0.6.0", - "spki 0.6.0", + "der", + "spki", ] [[package]] name = "polling" -version = "2.3.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899b00b9c8ab553c743b3e11e87c5c7d423b2a2de229ba95b24a756344748011" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" dependencies = [ "autocfg", "cfg-if", "libc", "log", "wepoll-ffi", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primeorder" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b54f7131b3dba65a2f414cf5bd25b66d4682e4608610668eae785750ba4c5b2" +dependencies = [ + "elliptic-curve", +] [[package]] name = "proc-macro-error" @@ -1039,18 +1022,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -1096,9 +1079,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", @@ -1107,26 +1090,26 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "rfc6979" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c86280f057430a52f4861551b092a01b419b8eacefc7c995eacb9dc132fe32" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint 0.4.9", + "crypto-bigint", "hmac", "zeroize", ] [[package]] name = "rsa" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf22754c49613d2b3b119f0e5d46e34a2c628a937e3024b8762de4e7d8c710b" +checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" dependencies = [ "byteorder", "digest", @@ -1135,8 +1118,9 @@ dependencies = [ "num-iter", "num-traits", "pkcs1", - "pkcs8 0.8.0", + "pkcs8", "rand_core", + "signature 1.6.4", "smallvec", "subtle", "zeroize", @@ -1144,9 +1128,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "scopeguard" @@ -1161,27 +1145,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", - "der 0.6.0", + "der", "generic-array", - "pkcs8 0.9.0", + "pkcs8", "subtle", "zeroize", ] [[package]] name = "serde" -version = "1.0.145" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -1190,9 +1174,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", @@ -1212,9 +1196,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -1229,21 +1213,33 @@ dependencies = [ "rand_core", ] +[[package]] +name = "signature" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "simple-auth" -version = "0.3.0" +version = "0.3.2" dependencies = [ "async-std", "async-trait", "base64", "clap", "configparser", + "http", "json", "jwt-simple", "lazy_static", "log", "regex", "serde", + "serde_json", "simple_logger", "tokio", ] @@ -1292,16 +1288,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der 0.5.1", -] - [[package]] name = "spki" version = "0.6.0" @@ -1309,7 +1295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der 0.6.0", + "der", ] [[package]] @@ -1326,9 +1312,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.102" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -1337,33 +1323,33 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -1401,9 +1387,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.21.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" dependencies = [ "autocfg", "bytes", @@ -1416,14 +1402,14 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", @@ -1432,15 +1418,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "value-bag" @@ -1472,9 +1458,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1482,9 +1468,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", @@ -1497,9 +1483,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -1509,9 +1495,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1519,9 +1505,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -1532,15 +1518,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -1586,19 +1572,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -1606,85 +1579,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "zeroize" diff --git a/Cargo.toml b/Cargo.toml index 2434003..63729ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "simple-auth" -version = "0.3.1" +version = "0.3.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,6 +15,9 @@ jwt-simple = "0.11.1" simple_logger = "4.0.0" log = "0.4.17" base64 = "0.13.1" +serde_json = "1.0" + +http = { git = "https://gitea.thegux.fr/rmanach/http", version = "0.1.6" } # useful for tests (embedded files should be delete in release ?) #rust-embed="6.4.1" diff --git a/README.md b/README.md index b5e57fc..a0238c6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ cargo build --release ``` ## Configuration - ### Store The store represents the credentials. For now, this a `.txt` file with plain passwords. You have to create one like: ```txt @@ -72,7 +71,7 @@ cargo test * set the following env variables: ```bash export SIMPLE_AUTH_URL="http://:" -export SIMPLE_AUTH_PUB_KEY="" # DO NOT USE THE ONE IN PRODUCTION ! +export SIMPLE_AUTH_PUB_KEY="" # DO NOT USE THIS ONE IN PRODUCTION ! ``` * run the server (if no one is running remotly) * run curl tests @@ -80,14 +79,14 @@ export SIMPLE_AUTH_PUB_KEY="" # DO NOT USE THE ONE IN PRODU cd tests/bash/ ./curling.bash && echo "passed" ``` -* run python requests tests +* run python tests ```bash # create a python venv cd tests/python python3 -m venv venv source venv/bin/activate -# intall the requirements +# install the requirements pip install -r requirements # launch the tests @@ -97,5 +96,5 @@ python -m unittest ## Documentation ```bash # add the '--open' arg to open the doc on a browser -cargo doc --no-deps +cargo doc -r --no-deps ``` diff --git a/src/config/mod.rs b/src/config/mod.rs index b82b271..bd20f7d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,4 +1,5 @@ -//! provides `Config` struct to load and validate `.ini` file +//! **config** module provides `Config` struct to load and validate `.ini` file. + mod config; pub use config::Config; diff --git a/src/http/message.rs b/src/http/message.rs deleted file mode 100644 index cbf4287..0000000 --- a/src/http/message.rs +++ /dev/null @@ -1,93 +0,0 @@ -use json; -use std::collections::HashMap; - -const JSON_DELIMITER: &'static str = ","; - -/// `HashMap` wrapper, represents the JSON response body -pub struct HTTPMessage { - message: HashMap, -} - -impl Default for HTTPMessage { - fn default() -> Self { - HTTPMessage { - message: HashMap::new(), - } - } -} - -/// try to convert `HTTPMessage` in `json::JsonValue` -impl TryInto for HTTPMessage { - type Error = String; - fn try_into(self) -> Result { - let message = format!(r#"{{{}}}"#, self.build_json()); - match json::parse(&message) { - Ok(r) => Ok(r), - Err(e) => Err(format!( - "unable to parse the HTTPMessage correctly: {}, err={}", - message, e - )), - } - } -} - -impl HTTPMessage { - pub fn put(&mut self, key: &str, value: &str) { - self.message.insert(key.to_string(), value.to_string()); - } - - /// associated function to build an HTTPMessage error - pub fn error(message: &str) -> Option { - let mut http_message = HTTPMessage::default(); - http_message.put("error", message); - - match message.try_into() { - Ok(m) => Some(m), - Err(e) => { - eprintln!( - "unable to parse the message: {} into JSON, err={}", - message, e - ); - return None; - } - } - } - - /// loops over all the HashMap keys, builds a JSON key value for each one and join them with `JSON_DELIMITER` - fn build_json(self) -> String { - let unstruct: Vec = self - .message - .keys() - .map(|k| format!(r#""{}":{:?}"#, k, self.message.get(k).unwrap())) - .collect(); - let joined = unstruct.join(JSON_DELIMITER); - joined - } -} - -#[test] -fn test_message() { - let mut http_message = HTTPMessage::default(); - http_message.put("email", "toto@toto.fr"); - http_message.put("password", "tata"); - - let mut json_result: Result = http_message.try_into(); - assert!(json_result.is_ok()); - - let mut json = json_result.unwrap(); - assert!(json.has_key("email")); - assert!(json.has_key("password")); - - let empty_http_message = HTTPMessage::default(); - json_result = empty_http_message.try_into(); - assert!(json_result.is_ok()); - - json = json_result.unwrap(); - assert_eq!("{}", json.dump().to_string()); - - let mut bad_http_message = HTTPMessage::default(); - bad_http_message.put("\"", ""); - - json_result = bad_http_message.try_into(); - assert!(json_result.is_err()); -} diff --git a/src/http/mod.rs b/src/http/mod.rs deleted file mode 100644 index 077d5b4..0000000 --- a/src/http/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! http module includes tools to parse an HTTP request and build and HTTP response - -pub mod message; -pub mod request; -pub mod response; -pub mod router; - -pub use message::HTTPMessage; -pub use request::{HTTPRequest, HTTPVersion}; -pub use response::{HTTPResponse, HTTPStatusCode}; -pub use router::ROUTER; diff --git a/src/http/request.rs b/src/http/request.rs deleted file mode 100644 index c4c7bc2..0000000 --- a/src/http/request.rs +++ /dev/null @@ -1,416 +0,0 @@ -//! request handles properly the incoming request -//! it will parse the request according to the HTTP message specifications -//! see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages -//! NOTE: only few parts of the specification has been implemented - -use json; -use lazy_static::lazy_static; -use regex::Regex; -use std::collections::VecDeque; - -use crate::utils::extract_json_value; - -type RequestParts = (String, VecDeque, String); - -const HTTP_REQUEST_SEPARATOR: &'static str = "\r\n"; -const NULL_CHAR: &'static str = "\0"; - -lazy_static! { - static ref HTTP_VERSION_REGEX: Regex = Regex::new("^HTTP/(1.1|1.0|2)$").unwrap(); -} - -#[derive(Debug, Copy, Clone)] -pub enum HTTPVersion { - Http1_0, - Http1_1, - Http2, - Unknown, -} - -impl Into for HTTPVersion { - fn into(self) -> String { - match self { - Self::Http1_0 => "HTTP/1.0".to_string(), - Self::Http1_1 => "HTTP/1.1".to_string(), - Self::Http2 => "HTTP/2".to_string(), - Self::Unknown => "UNKNOWN".to_string(), - } - } -} - -// TODO: not really satifying... could accept `String` too -impl From<&String> for HTTPVersion { - fn from(http_version: &String) -> Self { - match http_version.as_str() { - "HTTP/1.0" => Self::Http1_0, - "HTTP/1.1" => Self::Http1_1, - "HTTP/2" => Self::Http2, - _ => Self::Unknown, - } - } -} - -#[derive(Debug)] -pub struct HTTPStartLine { - method: String, - target: String, - version: HTTPVersion, -} - -impl HTTPStartLine { - fn new(method: String, target: String, version: HTTPVersion) -> Self { - HTTPStartLine { - method, - target, - version, - } - } - - fn parse(start_line: &str) -> Result { - // declare a new `start_line` var to borrow to &str `start_line` - let start_line = start_line.to_string(); - - let parts: Vec<&str> = start_line.split(" ").collect(); - if parts.len() < 3 { - return Err("unable to parse the start correctly"); - } - - let method = parts[0].to_string(); - let target = parts[1].to_string(); - let version = parts[2].to_string(); - - if !Self::check_version(&version) { - return Err("http version validation failed, unknown version"); - } - - Ok(HTTPStartLine::new( - method, - target, - HTTPVersion::from(&version), - )) - } - - fn check_version(version: &String) -> bool { - HTTP_VERSION_REGEX.is_match(version) - } - - pub fn is_valid(&self) -> bool { - return self.method != "" && self.target != ""; - } - - pub fn get_target(&self) -> String { - self.target.clone() - } -} - -impl Default for HTTPStartLine { - fn default() -> Self { - HTTPStartLine { - method: "".to_string(), - target: "".to_string(), - version: HTTPVersion::Unknown, - } - } -} - -impl Into for HTTPStartLine { - fn into(self) -> String { - let version: String = self.version.into(); - return format!("{} {} {}", self.method, self.target, version); - } -} - -/// represents an HTTP request body -/// for simplicity, only json body is accepted -#[derive(Debug)] -pub struct HTTPBody { - data: json::JsonValue, -} - -impl HTTPBody { - fn new(data: json::JsonValue) -> HTTPBody { - HTTPBody { data } - } - - pub fn get_data(&self) -> &json::JsonValue { - &self.data - } -} - -impl TryFrom for HTTPBody { - type Error = String; - fn try_from(body: String) -> Result { - let body = body.replace(NULL_CHAR, ""); - match json::parse(&body) { - Ok(v) => Ok(HTTPBody::new(v)), - Err(e) => Err(format!("during request body parsing details={}", e)), - } - } -} - -/// Represents an HTTP request (headers are not parsed) -#[derive(Debug)] -pub struct HTTPRequest { - pub start_line: HTTPStartLine, - pub body: Option, - // includes the client IP + port (should be in the headers) - pub addr: String, -} - -impl HTTPRequest { - /// split correctly the incoming request in order to get : - /// * start_line - /// * headers - /// * data (if exists) - fn get_request_parts(request: &str) -> Result { - // separate the body part from the start_line and the headers - let mut request_parts: VecDeque = request - .split(HTTP_REQUEST_SEPARATOR) - .map(|r| r.to_string()) - .collect(); - - if request_parts.len() < 3 { - return Err("request has no enough informations to be correctly parsed".to_string()); - } - let start_line = request_parts.pop_front().unwrap(); - let body = request_parts.pop_back().unwrap(); - - Ok((start_line, request_parts, body)) - } - - /// parse the request by spliting the incoming request with the separator `\r\n` - fn parse(request: &str) -> Result { - let request = request.to_string(); - - match HTTPRequest::get_request_parts(&request) { - Ok(rp) => { - let mut request = HTTPRequest::default(); - - let start_line = HTTPStartLine::parse(&rp.0); - match start_line { - Ok(v) => request.start_line = v, - Err(e) => log::error!("while parsing start_line details={}", e), - } - - let body = HTTPBody::try_from(rp.2); - match body { - Ok(v) => request.body = Some(v), - Err(e) => log::warn!("{}", e), - } - - return Ok(request); - } - Err(e) => { - return Err(e); - } - } - } - - /// retrieve value in `HTTPBody` (returns None if empty or does not exist) - pub fn get_body_value(&self, key: &str) -> Option { - match self.body { - Some(ref b) => match &b.data { - json::JsonValue::Object(d) => extract_json_value(&d, key), - _ => None, - }, - None => None, - } - } - - pub fn get_method(&self) -> String { - self.start_line.method.clone() - } - - #[allow(dead_code)] - pub fn is_valid(&self) -> bool { - return self.start_line.is_valid(); - } - - pub fn set_addr(&mut self, addr: String) { - self.addr = addr; - } -} - -impl Default for HTTPRequest { - fn default() -> Self { - HTTPRequest { - start_line: HTTPStartLine::default(), - body: None, - addr: "".to_string(), - } - } -} - -impl From<&str> for HTTPRequest { - fn from(request: &str) -> Self { - match Self::parse(request) { - Ok(v) => v, - Err(e) => { - log::error!("{}", e); - return HTTPRequest::default(); - } - } - } -} - -#[test] -fn test_request() { - struct Expect { - start_line: String, - body: Option, - is_valid: bool, - has_token: bool, - } - - let test_cases: [(String, Expect); 12] = [ - ( - "POST /get/ HTTP/1.1\r\n\r\n".to_string(), - Expect { - start_line: "POST /get/ HTTP/1.1".to_string(), - body: None, - is_valid: true, - has_token: false, - }, - ), - ( - "POST /refresh/ HTTP/2\r\n\r\n".to_string(), - Expect { - start_line: "POST /refresh/ HTTP/2".to_string(), - body: None, - is_valid: true, - has_token: false, - }, - ), - ( - "POST /validate/ HTTP/1.0\r\n\r\n".to_string(), - Expect { - start_line: "POST /validate/ HTTP/1.0".to_string(), - body: None, - is_valid: true, - has_token: false, - }, - ), - ( - "GET / HTTP/1.1\r\n\r\n".to_string(), - Expect { - start_line: "GET / HTTP/1.1".to_string(), - body: None, - is_valid: true, - has_token: false, - }, - ), - // intentionally add HTTP with no version number - ( - "OPTIONS /admin/2 HTTP/\r\nContent-Type: application/json\r\n".to_string(), - Expect { - start_line: " UNKNOWN".to_string(), - body: None, - is_valid: false, - has_token: false, - }, - ), - ( - "POST HTTP".to_string(), - Expect { - start_line: " UNKNOWN".to_string(), - body: None, - is_valid: false, - has_token: false - } - ), - ( - "".to_string(), - Expect { - start_line: " UNKNOWN".to_string(), - body: None, - is_valid: false, - has_token: false - } - ), - ( - "fjlqskjd /oks?id=65 HTTP/2\r\n\r\n".to_string(), - Expect { - start_line: "fjlqskjd /oks?id=65 HTTP/2".to_string(), - body: None, - is_valid: true, - has_token: false - } - ), - ( - " ".to_string(), - Expect { - start_line: " UNKNOWN".to_string(), - body: None, - is_valid: false, - has_token: false, - } - ), - ( - r#"lm //// skkss\r\ndkldklkdl\r\n"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}""#.to_string(), - Expect { - start_line: " UNKNOWN".to_string(), - body: Some(r#"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}"#.to_string()), - is_valid: false, - has_token: false - } - ), - ( - format!("{}\r\nuselessheaders\r\n{}", "POST /refresh/ HTTP/1.1", r#"{"access_token": "toto", "refresh_token": "tutu"}"#), - Expect { - start_line: "POST /refresh/ HTTP/1.1".to_string(), - body: Some(r#"{"access_token":"toto","refresh_token":"tutu"}"#.to_string()), - is_valid: true, - has_token: false - } - ), - ( - format!("{}\r\nuselessheaders\r\n{}", "POST /get/ HTTP/1.1", r#"{"token": "toto", "refresh_token": "tutu"}"#), - Expect { - start_line: "POST /get/ HTTP/1.1".to_string(), - body: Some(r#"{"token":"toto","refresh_token":"tutu"}"#.to_string()), - is_valid: true, - has_token: true - } - ), - ]; - - for (request, expect) in test_cases { - let http_request = HTTPRequest::from(request.as_str()); - assert_eq!(expect.is_valid, http_request.is_valid()); - - let token = http_request.get_body_value("token"); - let start_line: String = http_request.start_line.into(); - assert_eq!(expect.start_line, start_line); - - match http_request.body { - Some(v) => { - assert_eq!(expect.body.unwrap(), v.data.dump()) - } - None => continue, - } - - match expect.has_token { - true => assert!(token.is_some()), - false => assert!(token.is_none()), - } - } -} - -#[test] -fn test_http_body() { - let test_cases: [(&str, bool); 3] = [ - ("hello, how are you ?", false), - ("qsdfqsdffqsdffsq", false), - ( - r#"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}"#, - true, - ), - ]; - - for (body, is_valid) in test_cases { - match HTTPBody::try_from(body.to_string()) { - Ok(_) => assert!(is_valid), - Err(_) => assert!(!is_valid), - } - } -} diff --git a/src/http/response.rs b/src/http/response.rs deleted file mode 100644 index 451e876..0000000 --- a/src/http/response.rs +++ /dev/null @@ -1,172 +0,0 @@ -//! response handles the incoming request parsed `HTTPRequest` -//! it will build an HTTPResponse corresponding to the HTTP message specs. see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages -//! NOTE: only few parts of the specification has been implemented - -use super::{HTTPMessage, HTTPVersion}; -use json; - -#[derive(Debug, PartialEq, Clone)] -pub enum HTTPStatusCode { - Http200, - Http400, - Http403, - Http404, - Http500, -} - -impl Into for HTTPStatusCode { - fn into(self) -> String { - match self { - Self::Http200 => "200".to_string(), - Self::Http400 => "400".to_string(), - Self::Http404 => "404".to_string(), - Self::Http403 => "403".to_string(), - Self::Http500 => "500".to_string(), - } - } -} - -pub struct HTTPStatusLine { - version: HTTPVersion, - status_code: HTTPStatusCode, -} - -impl Default for HTTPStatusLine { - fn default() -> HTTPStatusLine { - HTTPStatusLine { - version: HTTPVersion::Http1_1, - status_code: HTTPStatusCode::Http400, - } - } -} - -impl Into for HTTPStatusLine { - fn into(self) -> String { - let version: String = self.version.into(); - let status_code: String = self.status_code.into(); - format! {"{} {}", version, status_code} - } -} - -impl HTTPStatusLine { - pub fn set_status_code(&mut self, code: HTTPStatusCode) { - self.status_code = code; - } - - #[allow(dead_code)] - pub fn get_status_code(&self) -> HTTPStatusCode { - self.status_code.clone() - } -} - -/// represents an HTTP response (headers are not parsed) -/// NOTE: for simplicity, only JSON body are accepted -pub struct HTTPResponse { - pub status_line: HTTPStatusLine, - body: json::JsonValue, -} - -impl Default for HTTPResponse { - fn default() -> Self { - HTTPResponse { - status_line: HTTPStatusLine::default(), - body: json::parse(r#"{"error": "the incoming request is not valid"}"#).unwrap(), - } - } -} - -impl Into for HTTPResponse { - fn into(self) -> String { - // move `self.body` into a new var - let b = self.body; - let body: String = json::stringify(b); - - let status_line: String = self.status_line.into(); - format!( - "{}\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}", - status_line, - body.len(), - body - ) - } -} - -impl HTTPResponse { - pub fn as_500(message: Option) -> Self { - let mut response = Self::default(); - - response - .status_line - .set_status_code(HTTPStatusCode::Http500); - - response.body = { - match message { - Some(m) => m, - None => json::parse(r#"{"error": "unexpected error occurred"}"#).unwrap(), - } - }; - - response - } - - pub fn as_404() -> Self { - let mut response = Self::default(); - - response - .status_line - .set_status_code(HTTPStatusCode::Http404); - response.body = json::parse(r#"{"error": "the url requested does not exist"}"#).unwrap(); - - response - } - - pub fn as_403() -> Self { - let mut response = HTTPResponse { - status_line: HTTPStatusLine::default(), - body: json::parse(r#"{"error": "invalid credentials"}"#).unwrap(), - }; - - response - .status_line - .set_status_code(HTTPStatusCode::Http403); - - response - } - - /// wrap the `Self::default()` associated func (not really clear) - pub fn as_400() -> Self { - Self::default() - } - - pub fn as_200(message: Option) -> Self { - let mut response = Self::default(); - - response - .status_line - .set_status_code(HTTPStatusCode::Http200); - - response.body = { - match message { - Some(m) => m, - None => json::parse(r#"{"status": "ok"}"#).unwrap(), - } - }; - - response - } - - /// builds an HTTP 200 response with the generated JWT - pub fn send_token(token: &str) -> Self { - let mut http_message = HTTPMessage::default(); - http_message.put("token", token); - - let message = { - match http_message.try_into() { - Ok(m) => m, - Err(_e) => json::parse(r#"{"token": "error.generation.token"}"#).unwrap(), - } - }; - - HTTPResponse::as_200(Some(message)) - } -} diff --git a/src/jwt/jwt.rs b/src/jwt/jwt.rs index 56f3aa8..f642376 100644 --- a/src/jwt/jwt.rs +++ b/src/jwt/jwt.rs @@ -5,6 +5,9 @@ use serde::{Deserialize, Serialize}; use std::collections::HashSet; use tokio::fs; +use crate::message::JWTMessage; +use crate::stores::Credentials; + #[derive(Serialize, Deserialize)] struct JWTCustomClaims { email: String, @@ -58,8 +61,8 @@ impl JWTSigner { verification_options } - /// builds and signs the token - pub fn sign(&self, email: String) -> Result { + /// sign builds and signs the token + pub fn sign(&self, credentials: Credentials) -> Result { let jwt_key = { match RS384KeyPair::from_pem(&self.private_key) { Ok(k) => k, @@ -69,13 +72,18 @@ impl JWTSigner { } }; let mut claims = Claims::with_custom_claims( - JWTCustomClaims { email }, + JWTCustomClaims { + email: credentials.get_email(), + }, Duration::from_hours(self.exp_time), ); claims.issuer = Some(self.issuer.clone()); match jwt_key.sign(claims) { - Ok(token) => Ok(token), + Ok(token) => { + // TODO: need to generate the refresh token + return Ok(serde_json::to_string(&JWTMessage::with_access(token)).unwrap()); + } Err(e) => { return Err(format!("unable to sign the token details={}", e)); } diff --git a/src/jwt/mod.rs b/src/jwt/mod.rs index 9b43d55..7eb999b 100644 --- a/src/jwt/mod.rs +++ b/src/jwt/mod.rs @@ -1,4 +1,5 @@ -//! simple module to read `.pem` files and sign the token +//! **jwt** module aims to read `.pem` files and sign/validate the token. + mod jwt; pub use jwt::JWTSigner; diff --git a/src/main.rs b/src/main.rs index d16c45a..90f47ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ mod config; -mod http; mod jwt; +mod message; +mod router; mod stores; -mod utils; use clap::Parser; use configparser::ini::Ini; @@ -12,8 +12,8 @@ use tokio::{ time::{timeout, Duration}, }; +use crate::router::ROUTER; use config::Config; -use http::ROUTER; #[derive(Parser)] #[clap(author, version, about, long_about = None)] @@ -67,7 +67,7 @@ async fn main() { } } -/// parses the incoming request (partial spec implementation) and build an HTTP response +/// handle_connection parses the incoming request and builds an HTTP response async fn handle_connection(mut stream: TcpStream, addr: String, config: Config) { log::info!("client connected: {}", addr); @@ -90,7 +90,7 @@ async fn handle_connection(mut stream: TcpStream, addr: String, config: Config) } let request_string = std::str::from_utf8(&message).unwrap(); - let response = ROUTER.route(request_string, addr.clone(), config).await; + let response = ROUTER.route(request_string, config).await; let response_str: String = response.into(); stream.write(response_str.as_bytes()).await.unwrap(); diff --git a/src/message/message.rs b/src/message/message.rs new file mode 100644 index 0000000..8b365c8 --- /dev/null +++ b/src/message/message.rs @@ -0,0 +1,48 @@ +use serde::Serialize; + +#[derive(Serialize)] +/// JWTMessage aims to have a generic struct to build JSON HTTP response message with JWT informations +pub struct JWTMessage { + #[serde(skip_serializing_if = "String::is_empty")] + access_token: String, + #[serde(skip_serializing_if = "String::is_empty")] + refresh_token: String, + #[serde(skip_serializing_if = "String::is_empty")] + pubkey: String, +} + +impl JWTMessage { + pub fn with_access(access_token: String) -> Self { + JWTMessage { + access_token: access_token, + refresh_token: "".to_string(), + pubkey: "".to_string(), + } + } + + pub fn with_pubkey(pubkey: String) -> Self { + JWTMessage { + access_token: "".to_string(), + refresh_token: "".to_string(), + pubkey: base64::encode(pubkey), + } + } +} + +#[derive(Serialize, Default)] +/// ValidationMessage aims to build a JSON HTTP response body for JWT validation +pub struct ValidationMessage { + valid: bool, + #[serde(skip_serializing_if = "String::is_empty")] + reason: String, +} + +impl ValidationMessage { + pub fn set_valid(&mut self, valid: bool) { + self.valid = valid; + } + + pub fn set_reason(&mut self, reason: &str) { + self.reason = reason.to_string(); + } +} diff --git a/src/message/mod.rs b/src/message/mod.rs new file mode 100644 index 0000000..072badf --- /dev/null +++ b/src/message/mod.rs @@ -0,0 +1,5 @@ +//! **message** module holds all structs to manage JSON response body for the authentication. + +mod message; + +pub use message::{JWTMessage, ValidationMessage}; diff --git a/src/router/mod.rs b/src/router/mod.rs new file mode 100644 index 0000000..343295a --- /dev/null +++ b/src/router/mod.rs @@ -0,0 +1,4 @@ +//! **router** module includes all the handlers to get and validate JWT. + +mod router; +pub use router::ROUTER; diff --git a/src/http/router.rs b/src/router/router.rs similarity index 50% rename from src/http/router.rs rename to src/router/router.rs index 2ddaae5..63dcd00 100644 --- a/src/http/router.rs +++ b/src/router/router.rs @@ -1,29 +1,32 @@ -//! router aims to handle correctly the request corresponding to the target -//! it implements all the logic to build an `HTTPResponse` +use http::{HTTPRequest, HTTPResponse, JSONMessage}; +use json::JsonValue; -use base64; -use json; - -use super::{HTTPMessage, HTTPRequest, HTTPResponse}; use crate::config::Config; use crate::jwt::JWTSigner; -use crate::stores::{FileStore, Store}; +use crate::message::{JWTMessage, ValidationMessage}; +use crate::stores::{Credentials, FileStore, Store}; // TODO: must be mapped with corresponding handler const GET_ROUTE: &'static str = "/get/"; const VALIDATE_ROUTE: &'static str = "/validate/"; const PUBKEY_ROUTE: &'static str = "/pubkey/"; -async fn handle_get(request: HTTPRequest, config: Config, method: &str) -> HTTPResponse { +async fn handle_get(request: HTTPRequest<'_>, config: Config, method: &str) -> HTTPResponse { if method.trim().to_lowercase() != "post" { return HTTPResponse::as_400(); } let mut store = FileStore::new(config.filestore_path.clone()); - match &request.body { - Some(ref b) => { - let credentials = store.is_auth(&b.get_data()).await; - if credentials.is_none() { + + match request.get_body() { + Some(d) => { + let credentials = Credentials::from(d); + if credentials.is_empty() { + log::error!("unable to parse the credentials correctly from the incoming request"); + return HTTPResponse::as_400(); + } + + if !store.is_auth(&credentials).await { return HTTPResponse::as_403(); } @@ -31,16 +34,16 @@ async fn handle_get(request: HTTPRequest, config: Config, method: &str) -> HTTPR match JWTSigner::new(config).await { Ok(s) => s, Err(e) => { - let message = HTTPMessage::error(&e); + let message = JSONMessage::error(&e); return HTTPResponse::as_500(message); } } }; - match jwt_signer.sign(credentials.unwrap().email) { - Ok(t) => HTTPResponse::send_token(&t), + match jwt_signer.sign(credentials) { + Ok(t) => send_token(&t), Err(e) => { - let message = HTTPMessage::error(&e); + let message = JSONMessage::error(&e); return HTTPResponse::as_500(message); } } @@ -49,10 +52,10 @@ async fn handle_get(request: HTTPRequest, config: Config, method: &str) -> HTTPR } } -/// validates the token by checking: +/// handle_validate validates the token by checking: /// * expiration time /// * signature -async fn handle_validate(request: HTTPRequest, config: Config, method: &str) -> HTTPResponse { +async fn handle_validate(request: HTTPRequest<'_>, config: Config, method: &str) -> HTTPResponse { if request.get_method().trim().to_lowercase() != method { return HTTPResponse::as_400(); } @@ -61,11 +64,10 @@ async fn handle_validate(request: HTTPRequest, config: Config, method: &str) -> match request.get_body_value("token") { Some(t) => t, None => { - let mut message = HTTPMessage::default(); - message.put("valid", "false"); - message.put("reason", "no token provided in the request body"); - let json = message.try_into().unwrap(); + let mut message = ValidationMessage::default(); + message.set_reason("no token provided in the request body"); + let json = json::parse(&serde_json::to_string(&message).unwrap()).unwrap(); return HTTPResponse::as_200(Some(json)); } } @@ -75,30 +77,29 @@ async fn handle_validate(request: HTTPRequest, config: Config, method: &str) -> match JWTSigner::new(config).await { Ok(s) => s, Err(e) => { - let message = HTTPMessage::error(&e); + let message = JSONMessage::error(&e); let json = message.try_into().unwrap(); return HTTPResponse::as_500(Some(json)); } } }; - let mut message = HTTPMessage::default(); + let mut message = ValidationMessage::default(); match jwt_signer.validate(&token) { Ok(()) => { - message.put("valid", "true"); + message.set_valid(true); } Err(e) => { - message.put("valid", "false"); - message.put("reason", &e); + message.set_reason(&e); } } - let json: json::JsonValue = message.try_into().unwrap(); + let json: JsonValue = json::parse(&serde_json::to_string(&message).unwrap()).unwrap(); HTTPResponse::as_200(Some(json)) } -/// returns the JWT public key in base64 encoded -async fn handle_public_key(request: HTTPRequest, config: Config, method: &str) -> HTTPResponse { +/// handle_public_key returns the JWT public key in base64 encoded +async fn handle_public_key(request: HTTPRequest<'_>, config: Config, method: &str) -> HTTPResponse { if request.get_method().trim().to_lowercase() != method { return HTTPResponse::as_400(); } @@ -107,7 +108,7 @@ async fn handle_public_key(request: HTTPRequest, config: Config, method: &str) - match JWTSigner::new(config).await { Ok(s) => s, Err(e) => { - let message = HTTPMessage::error(&e); + let message = JSONMessage::error(&e); let json = message.try_into().unwrap(); return HTTPResponse::as_500(Some(json)); } @@ -115,25 +116,18 @@ async fn handle_public_key(request: HTTPRequest, config: Config, method: &str) - }; let public_key = jwt_signer.get_public_key(); + let message = serde_json::to_string(&JWTMessage::with_pubkey(public_key)).unwrap(); - let mut message = HTTPMessage::default(); - message.put("pubkey", &base64::encode(public_key)); - - let json = message.try_into().unwrap(); - HTTPResponse::as_200(Some(json)) + HTTPResponse::as_200(Some(json::parse(&message).unwrap())) } pub struct Router; impl Router { - /// routes the request to the corresponding handling method - pub async fn route(&self, request_str: &str, addr: String, config: Config) -> HTTPResponse { - let mut request = HTTPRequest::from(request_str); - request.set_addr(addr); - - let target = request.start_line.get_target(); - - match target.as_str() { + /// route routes the request to the corresponding handler + pub async fn route(&self, request_str: &str, config: Config) -> HTTPResponse { + let request = HTTPRequest::from(request_str); + match request.get_target() { GET_ROUTE => handle_get(request, config, "post").await, VALIDATE_ROUTE => handle_validate(request, config, "post").await, PUBKEY_ROUTE => handle_public_key(request, config, "get").await, @@ -142,20 +136,27 @@ impl Router { } } -// this MUST be used like a Singleton +/// send_token generates an HTTPResponse with the new token +pub fn send_token(jwt_message: &str) -> HTTPResponse { + let message = if jwt_message != "" { + jwt_message + } else { + r#"{"token": "error.generation.token"}"# + }; + HTTPResponse::as_200(Some(json::parse(message).unwrap())) +} + +// this **MUST** be used like a Singleton pub const ROUTER: Router = Router {}; #[tokio::test] async fn test_route() { - use super::HTTPStatusCode; + use http::HTTPStatusCode; let router: &Router = &ROUTER; let config: Config = Config::default(); let request_str = "POST /get/ HTTP/1.1\r\n\r\n"; - let response: HTTPResponse = router.route(request_str, "".to_string(), config).await; - assert_eq!( - HTTPStatusCode::Http400, - response.status_line.get_status_code() - ); + let response: HTTPResponse = router.route(request_str, config).await; + assert_eq!(HTTPStatusCode::Http400, response.get_status_code()); } diff --git a/src/stores/file.rs b/src/stores/file.rs index 3f0cb1b..5783320 100644 --- a/src/stores/file.rs +++ b/src/stores/file.rs @@ -1,10 +1,9 @@ use async_trait::async_trait; -use json; use std::path::Path; use super::store::{Credentials, Store}; -/// references a credentials store file +/// FileStore references a credentials store file pub struct FileStore { path: String, credentials: Vec, @@ -18,8 +17,9 @@ impl FileStore { } } - /// loads and reads the file asynchonously - /// parses the file line by line to retrieve the credentials + /// parse_contents loads and reads the file asynchonously + /// + /// It parses the file line by line to retrieve the credentials async fn parse_contents(&mut self) { let contents = tokio::fs::read_to_string(&self.path).await; let mut credentials: Vec = vec![]; @@ -47,41 +47,31 @@ impl FileStore { self.credentials = credentials; } - /// checks if the credentials exist in the `FileStore` - fn auth(&self, email: String, password: String) -> Option { + /// auth checks if the credentials exist in the `FileStore` + fn auth(&self, email: String, password: String) -> bool { let credentials: Vec<&Credentials> = self .credentials .iter() - .filter(|x| x.email == email && x.password == password) + .filter(|x| *x.get_email() == email && *x.get_password() == password) .collect(); if credentials.len() == 1 { - // no need to store the password again - return Some(Credentials::new( - credentials[0].email.clone(), - "".to_string(), - )); + return true; } - None + false } } #[async_trait] impl Store for FileStore { - async fn is_auth(&mut self, data: &json::JsonValue) -> Option { + async fn is_auth(&mut self, credentials: &Credentials) -> bool { // ensure that the store file already exists even after its instanciation if !Path::new(&self.path).is_file() { log::error!("{} path referencing file store does not exist", self.path); - return None; - } - - let credentials = Credentials::from(data); - if credentials.is_empty() { - log::error!("unable to parse the credentials correctly from the incoming request"); - return None; + return false; } self.parse_contents().await; - self.auth(credentials.email, credentials.password) + self.auth(credentials.get_email(), credentials.get_password()) } } @@ -90,13 +80,14 @@ async fn test_store() { use std::env; let root_path = env::var("CARGO_MANIFEST_DIR").unwrap(); - // TODO: path::Path should be better let store_path = format!("{}/{}/{}/{}", root_path, "tests", "data", "store.txt"); let mut store = FileStore::new(store_path); let data = json::parse(r#"{"email": "toto@toto.fr", "password": "tata"}"#).unwrap(); - let credentials = store.is_auth(&data).await; - assert_eq!(false, credentials.is_none()); - assert_eq!(credentials.unwrap().email, "toto@toto.fr"); + let credentials = Credentials::from(&data); + assert_eq!(credentials.get_email(), "toto@toto.fr"); + + let is_auth = store.is_auth(&credentials).await; + assert_eq!(true, is_auth); } diff --git a/src/stores/mod.rs b/src/stores/mod.rs index 2a768fc..ae56d8e 100644 --- a/src/stores/mod.rs +++ b/src/stores/mod.rs @@ -1,8 +1,7 @@ -//! store module lists interfaces available to check request credentials -//! each store must implement the trait `is_auth` -//! two stores are available : +//! **store** module lists interfaces available to check credentials. Each store must implement the trait `is_auth`. +//! +//! For now one store is available: //! * `FileStore`: credentials stored in a text file (like **/etc/passwd**) -//! * `DBStore`: credentials stored in a database (TODO) mod file; mod store; diff --git a/src/stores/store.rs b/src/stores/store.rs index f034103..e5fa8fb 100644 --- a/src/stores/store.rs +++ b/src/stores/store.rs @@ -1,47 +1,55 @@ use async_trait::async_trait; -use json; - -use crate::utils::extract_json_value; +use json::JsonValue; +use serde::Deserialize; #[async_trait] pub trait Store { - async fn is_auth(&mut self, data: &json::JsonValue) -> Option; + async fn is_auth(&mut self, data: &Credentials) -> bool; } -#[derive(Default, Debug)] +#[derive(Default, Debug, Deserialize)] pub struct Credentials { - pub email: String, - pub password: String, + email: String, + password: String, } +/// Credentials represents the incoming user credentials for authentication checking impl Credentials { pub fn new(email: String, password: String) -> Self { Credentials { email, password } } + pub fn get_email(&self) -> String { + self.email.clone() + } + + pub fn get_password(&self) -> String { + self.password.clone() + } + pub fn is_empty(&self) -> bool { self.email == "" || self.password == "" } } -impl From<&json::JsonValue> for Credentials { - fn from(data: &json::JsonValue) -> Self { - let mut credentials = Credentials::default(); - match data { - json::JsonValue::Object(ref d) => { - credentials.email = extract_json_value(&d, "email").unwrap_or("".to_string()); - credentials.password = extract_json_value(&d, "password").unwrap_or("".to_string()); +// TODO: could be less restrictive with `From<&str>` +impl From<&JsonValue> for Credentials { + fn from(data: &JsonValue) -> Self { + let res = serde_json::from_str(&data.dump()); + match res { + Ok(c) => c, + Err(e) => { + log::warn!("unable to deserialize credentials: {}", e); + return Credentials::default(); } - _ => return credentials, } - credentials } } #[test] fn test_credentials() { struct Expect { - data: json::JsonValue, + data: JsonValue, is_empty: bool, } let test_cases: [Expect; 2] = [ diff --git a/src/utils/mod.rs b/src/utils/mod.rs deleted file mode 100644 index 4815b85..0000000 --- a/src/utils/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! includes utility function, that's all ! -mod utils; - -pub use utils::extract_json_value; diff --git a/src/utils/utils.rs b/src/utils/utils.rs deleted file mode 100644 index e330062..0000000 --- a/src/utils/utils.rs +++ /dev/null @@ -1,30 +0,0 @@ -use json::object::Object; - -/// extracts JSON value from a key -pub fn extract_json_value(data: &Object, key: &str) -> Option { - match data.get(key) { - Some(u) => match u.as_str() { - Some(s) => return Some(s.to_string()), - None => None, - }, - None => None, - } -} - -#[test] -fn test_extract_json_value() { - let test_cases: [(json::JsonValue, bool, bool); 3] = [ - (json::parse(r#"{"test": ""}"#).unwrap(), true, true), - (json::parse(r#"{}"#).unwrap(), true, false), - (json::parse(r#"[]"#).unwrap(), false, false), - ]; - - for (value, is_valid, has_key) in test_cases { - match value { - json::JsonValue::Object(d) => { - assert_eq!(has_key, extract_json_value(&d, "test").is_some()); - } - _ => assert!(!is_valid), - } - } -} diff --git a/tests/bash/curling.bash b/tests/bash/curling.bash index 5bd0be3..bee216a 100755 --- a/tests/bash/curling.bash +++ b/tests/bash/curling.bash @@ -16,15 +16,31 @@ fi for i in {0..10} do http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/get/ -d '{"username":"toto", "password":"tutu"}') - if [ $http_response != "403" ] + if [ $http_response != "400" ] then - echo "bad http status code : ${http_response}, expect 200" + echo "bad http status code : ${http_response}, expect 400" exit 1 fi - if [ "$(cat response.txt | jq -r '.error')" != "invalid credentials" ] + if [ "$(cat response.txt | jq -r '.error')" != "bad request" ] then - echo "bad data returned, expect : invalid credentials" + echo "bad data returned, expect : bad request" + exit 1 + fi +done + +for i in {0..10} +do + http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/get/ -d '{"email":"toto", "password":"tutu"}') + if [ $http_response != "403" ] + then + echo "bad http status code : ${http_response}, expect 403" + exit 1 + fi + + if [ "$(cat response.txt | jq -r '.error')" != "url forbidden" ] + then + echo "bad data returned, expect : url forbidden" exit 1 fi done @@ -35,7 +51,7 @@ do http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/ge/ -d '{"username":"toto", "password":"tutu"}') if [ $http_response != "404" ] then - echo "bad http status code : ${http_response}, expect 400" + echo "bad http status code : ${http_response}, expect 404" exit 1 fi done @@ -46,7 +62,7 @@ do http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/pubkey/) if [ $http_response != "200" ] then - echo "bad http status code : ${http_response}, expect 400" + echo "bad http status code : ${http_response}, expect 200" exit 1 fi done diff --git a/tests/python/test_requests.py b/tests/python/test_requests.py index 16be103..e1c7b19 100644 --- a/tests/python/test_requests.py +++ b/tests/python/test_requests.py @@ -22,7 +22,7 @@ class TestResponse(TestCase): self.assertEqual(resp.status_code, 200, "bad status code returned") self.assertIsNotNone(resp.json(), "response data can't be empty") - token = resp.json()["token"] + token = resp.json()["access_token"] jwt_decoded = jwt.decode( token, pubkey or self.pub_key, @@ -48,14 +48,14 @@ class TestResponse(TestCase): ) self.assertEqual(resp.status_code, 200, "bad status code returned") self.assertIsNotNone(resp.json(), "response data can't be empty") - self.assertEqual(resp.json()["valid"], "false", "bad status returned") + self.assertEqual(resp.json()["valid"], False, "bad status returned") self.assertEqual(resp.json()["reason"], "no token provided in the request body") def test_validate_target_empty_token(self): resp = requests.post(URL + "/validate/", json={"tutu": "tutu", "token": ""}) self.assertEqual(resp.status_code, 200, "bad status code returned") self.assertIsNotNone(resp.json(), "response data can't be empty") - self.assertEqual(resp.json()["valid"], "false", "bad status returned") + self.assertEqual(resp.json()["valid"], False, "bad status returned") self.assertEqual( resp.json()["reason"], "token validation failed details=JWT compact encoding error", @@ -67,7 +67,7 @@ class TestResponse(TestCase): resp = requests.post(URL + "/validate/", json={"token": token}) self.assertEqual(resp.status_code, 200, "bad status code returned") self.assertIsNotNone(resp.json(), "response data can't be empty") - self.assertEqual(resp.json()["valid"], "true", "bad status returned") + self.assertEqual(resp.json()["valid"], True, "bad status returned") # TODO: must be updated after implementing `/refresh/` url handler def test_refresh_target(self): @@ -78,7 +78,7 @@ class TestResponse(TestCase): self.assertIsNotNone(resp.json(), "response data can't be empty") self.assertEqual( resp.json()["error"], - "the url requested does not exist", + "url not found", "bad status returned", ) @@ -88,7 +88,7 @@ class TestResponse(TestCase): self.assertIsNotNone(resp.json(), "response data must not be empty") self.assertEqual( resp.json()["error"], - "the incoming request is not valid", + "bad request", "invalid error message returned", ) @@ -98,7 +98,7 @@ class TestResponse(TestCase): self.assertIsNotNone(resp.json(), "response data must not be empty") self.assertEqual( resp.json()["error"], - "invalid credentials", + "url forbidden", "invalid error message returned", ) @@ -110,7 +110,7 @@ class TestResponse(TestCase): self.assertIsNotNone(resp.json(), "response data must not be empty") self.assertEqual( resp.json()["error"], - "the url requested does not exist", + "url not found", "invalid error message returned", ) @@ -133,6 +133,6 @@ class TestResponse(TestCase): self.assertIsNotNone(resp.json(), "response data must not be empty") self.assertEqual( resp.json()["error"], - "the incoming request is not valid", + "bad request", "invalid error message returned", )