From ed53fbc9097370feeda1c5507878933643a9bcc5 Mon Sep 17 00:00:00 2001 From: Yigit Sever Date: Sat, 10 Apr 2021 14:16:41 +0300 Subject: Trying to auth --- .gitignore | 1 + Cargo.lock | 566 ++++++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 10 +- README.md | 8 +- TODO.md | 4 + src/auth.rs | 112 +++++++++++ src/error.rs | 63 +++++++ src/handlers.rs | 18 ++ src/main.rs | 2 + src/routes.rs | 38 +++- src/schema.rs | 14 +- 11 files changed, 642 insertions(+), 194 deletions(-) create mode 100644 src/auth.rs create mode 100644 src/error.rs diff --git a/.gitignore b/.gitignore index 53d254d..ca9689c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target +/secrets tags.lock tags.temp diff --git a/Cargo.lock b/Cargo.lock index 45ae0a0..ccc00f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,6 +9,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" + [[package]] name = "atty" version = "0.2.14" @@ -17,7 +23,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -63,6 +69,12 @@ dependencies = [ "safemem", ] +[[package]] +name = "bumpalo" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" + [[package]] name = "byteorder" version = "1.4.3" @@ -71,15 +83,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "0.5.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" [[package]] -name = "bytes" -version = "1.0.1" +name = "cc" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" @@ -104,7 +116,7 @@ dependencies = [ "num-traits", "serde", "time", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -131,12 +143,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "env_logger" version = "0.6.2" @@ -157,30 +163,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "form_urlencoded" -version = "1.0.1" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "matches", - "percent-encoding", + "foreign-types-shared", ] [[package]] -name = "fuchsia-zircon" -version = "0.3.3" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "form_urlencoded" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] [[package]] name = "futures" @@ -239,7 +244,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-task", - "pin-project-lite 0.2.6", + "pin-project-lite", "pin-utils", "slab", ] @@ -280,24 +285,28 @@ dependencies = [ name = "gradecoin" version = "0.1.0" dependencies = [ + "anyhow", "chrono", + "jsonwebtoken", "log", - "parking_lot", + "openssl", + "parking_lot 0.10.2", "pretty_env_logger", "serde", "serde_json", "serde_test", + "thiserror", "tokio", "warp", ] [[package]] name = "h2" -version = "0.2.7" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +checksum = "fc018e188373e2777d0ef2467ebff62a08e66c3f5857b23c8fbec3018210dc00" dependencies = [ - "bytes 0.5.6", + "bytes", "fnv", "futures-core", "futures-sink", @@ -308,7 +317,6 @@ dependencies = [ "tokio", "tokio-util", "tracing", - "tracing-futures", ] [[package]] @@ -325,7 +333,7 @@ checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855" dependencies = [ "base64 0.13.0", "bitflags", - "bytes 1.0.1", + "bytes", "headers-core", "http", "mime", @@ -357,19 +365,20 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" dependencies = [ - "bytes 1.0.1", + "bytes", "fnv", "itoa", ] [[package]] name = "http-body" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" +checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737" dependencies = [ - "bytes 0.5.6", + "bytes", "http", + "pin-project-lite", ] [[package]] @@ -395,11 +404,11 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.10" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a6f157065790a3ed2f88679250419b5cdd96e714a0d65f7797fd337186e96bb" +checksum = "8bf09f61b52cfcf4c00de50df88ae423d6c02354e385a86341133b5338630ad1" dependencies = [ - "bytes 0.5.6", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -409,7 +418,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project 1.0.6", + "pin-project", "socket2", "tokio", "tower-service", @@ -440,20 +449,20 @@ dependencies = [ [[package]] name = "input_buffer" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754" +checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" dependencies = [ - "bytes 0.5.6", + "bytes", ] [[package]] -name = "iovec" -version = "0.1.4" +name = "instant" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" dependencies = [ - "libc", + "cfg-if 1.0.0", ] [[package]] @@ -463,13 +472,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "js-sys" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" +dependencies = [ + "base64 0.12.3", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", ] [[package]] @@ -493,6 +515,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lock_api" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.14" @@ -532,33 +563,24 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.23" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", "libc", "log", "miow", - "net2", - "slab", - "winapi 0.2.8", + "ntapi", + "winapi", ] [[package]] name = "miow" -version = "0.2.2" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "winapi", ] [[package]] @@ -580,14 +602,23 @@ dependencies = [ ] [[package]] -name = "net2" -version = "0.2.37" +name = "ntapi" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", ] [[package]] @@ -609,20 +640,74 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + [[package]] name = "opaque-debug" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-sys" +version = "0.9.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ - "lock_api", - "parking_lot_core", + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api 0.4.3", + "parking_lot_core 0.8.3", ] [[package]] @@ -636,42 +721,47 @@ dependencies = [ "libc", "redox_syscall 0.1.57", "smallvec", - "winapi 0.3.9", + "winapi", ] [[package]] -name = "percent-encoding" -version = "2.1.0" +name = "parking_lot_core" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.5", + "smallvec", + "winapi", +] [[package]] -name = "pin-project" -version = "0.4.28" +name = "pem" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" dependencies = [ - "pin-project-internal 0.4.28", + "base64 0.13.0", + "once_cell", + "regex", ] [[package]] -name = "pin-project" -version = "1.0.6" +name = "percent-encoding" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6" -dependencies = [ - "pin-project-internal 1.0.6", -] +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] -name = "pin-project-internal" -version = "0.4.28" +name = "pin-project" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" +checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6" dependencies = [ - "proc-macro2", - "quote", - "syn", + "pin-project-internal", ] [[package]] @@ -685,12 +775,6 @@ dependencies = [ "syn", ] -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - [[package]] name = "pin-project-lite" version = "0.2.6" @@ -703,6 +787,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + [[package]] name = "ppv-lite86" version = "0.2.10" @@ -863,7 +953,22 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", ] [[package]] @@ -932,14 +1037,14 @@ dependencies = [ [[package]] name = "serde_urlencoded" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" dependencies = [ - "dtoa", + "form_urlencoded", "itoa", + "ryu", "serde", - "url", ] [[package]] @@ -955,6 +1060,26 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +dependencies = [ + "libc", +] + +[[package]] +name = "simple_asn1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" +dependencies = [ + "chrono", + "num-bigint", + "num-traits", +] + [[package]] name = "slab" version = "0.4.2" @@ -969,15 +1094,20 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "socket2" -version = "0.3.19" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" dependencies = [ - "cfg-if 1.0.0", "libc", - "winapi 0.3.9", + "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "syn" version = "1.0.68" @@ -1000,7 +1130,7 @@ dependencies = [ "rand 0.8.3", "redox_syscall 0.2.5", "remove_dir_all", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1012,6 +1142,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.44" @@ -1020,7 +1170,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1040,57 +1190,70 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "0.2.25" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722" dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "iovec", - "lazy_static", + "autocfg", + "bytes", + "libc", "memchr", "mio", - "pin-project-lite 0.1.12", - "slab", + "num_cpus", + "once_cell", + "parking_lot 0.11.1", + "pin-project-lite", + "signal-hook-registry", "tokio-macros", + "winapi", ] [[package]] name = "tokio-macros" -version = "0.2.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" +checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "tokio-stream" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e177a5d8c3bf36de9ebe6d58537d8879e964332f93fb3339e43f618c81361af0" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-tungstenite" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9e878ad426ca286e4dcae09cbd4e1973a7f8987d97570e2469703dd7f5720c" +checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b" dependencies = [ "futures-util", "log", - "pin-project 0.4.28", + "pin-project", "tokio", "tungstenite", ] [[package]] name = "tokio-util" -version = "0.3.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +checksum = "5143d049e85af7fbc36f5454d990e62c2df705b3589f123b71f441b6b59f443f" dependencies = [ - "bytes 0.5.6", + "bytes", "futures-core", "futures-sink", "log", - "pin-project-lite 0.1.12", + "pin-project-lite", "tokio", ] @@ -1108,7 +1271,7 @@ checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.6", + "pin-project-lite", "tracing-core", ] @@ -1121,16 +1284,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project 1.0.6", - "tracing", -] - [[package]] name = "try-lock" version = "0.2.3" @@ -1139,18 +1292,18 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tungstenite" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23" +checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" dependencies = [ - "base64 0.12.3", + "base64 0.13.0", "byteorder", - "bytes 0.5.6", + "bytes", "http", "httparse", "input_buffer", "log", - "rand 0.7.3", + "rand 0.8.3", "sha-1", "url", "utf-8", @@ -1204,6 +1357,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.2.1" @@ -1216,18 +1375,18 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "urlencoding" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9232eb53352b4442e40d7900465dfc534e8cb2dc8f18656fcb2ac16112b5593" - [[package]] name = "utf-8" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" +[[package]] +name = "vcpkg" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" + [[package]] name = "version_check" version = "0.9.3" @@ -1246,11 +1405,11 @@ dependencies = [ [[package]] name = "warp" -version = "0.2.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41be6df54c97904af01aa23e613d4521eed7ab23537cede692d4058f6449407" +checksum = "332d47745e9a0c38636dbd454729b147d16bd1ed08ae67b3ab281c4506771054" dependencies = [ - "bytes 0.5.6", + "bytes", "futures", "headers", "http", @@ -1259,17 +1418,18 @@ dependencies = [ "mime", "mime_guess", "multipart", - "pin-project 0.4.28", + "percent-encoding", + "pin-project", "scoped-tls", "serde", "serde_json", "serde_urlencoded", "tokio", + "tokio-stream", "tokio-tungstenite", + "tokio-util", "tower-service", "tracing", - "tracing-futures", - "urlencoding", ] [[package]] @@ -1285,10 +1445,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] -name = "winapi" -version = "0.2.8" +name = "wasm-bindgen" +version = "0.2.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" + +[[package]] +name = "web-sys" +version = "0.3.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "winapi" @@ -1300,12 +1518,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1318,7 +1530,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1326,13 +1538,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] diff --git a/Cargo.toml b/Cargo.toml index a203a6f..cffb196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,13 +7,17 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -warp = "0.2.0" -tokio = { version = "0.2.9", features = ["macros"] } -serde = { version = "1.0.104", features = ["derive"] } +warp = "0.3" +tokio = { version = "1", features = ["full"] } +serde = { version = "1.0.125", features = ["derive"] } chrono = { version = "0.4.10", features = ["serde"] } log = "0.4.8" +anyhow = "1.0.40" pretty_env_logger = "0.3.1" parking_lot = "0.10.0" +thiserror = "1.0" +jsonwebtoken = "7" +openssl = "0.10.28" [dev-dependencies] serde_json = "1.0.44" diff --git a/README.md b/README.md index 664336c..33da21f 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,12 @@ $ curl --location --request POST 'localhost:8080/transaction' --header 'Content- # how? ## authentication -Students generate their own `keypairs` and authenticate with their METU Student IDs. -Some JWT scheme, coming up. - -Authenticated students propose transactions, between them and another node (=public keys) or between the grader (=bank) and themselves. +- Student generates a 2048 bit RSA Public Key (PK) / Private Key (PR) pair (available in python, c++, rust, gpg) +- They then encrypt their PKs and Student IDs with Gradecoin's PK (will be published) +- They use their PR as the signing key for JWTs ## transactions +Students propose transactions, between them and another node (=public keys) or between the grader (=bank) and themselves. Transactions are `signed` using the proposers private key. (This whole public/private key + signing process will require some crypto dependency, **todo**) diff --git a/TODO.md b/TODO.md index 7b58d96..4810390 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,8 @@ # TODO + +## Schema +- [ ] It would be a good idea to keep blockchain and users in a database and only have `pending_transactions` in memory https://blog.logrocket.com/create-an-async-crud-web-service-in-rust-with-warp/ + ## Process - [ ] we need our own representation of students and their grades, "there is no blockchain" diff --git a/src/auth.rs b/src/auth.rs new file mode 100644 index 0000000..e22262c --- /dev/null +++ b/src/auth.rs @@ -0,0 +1,112 @@ +use crate::error::Error; +use crate::schema::{Db, Transaction}; +use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation}; +use serde::{Deserialize, Serialize}; +use warp::header::headers_cloned; +use warp::http::header::{HeaderMap, HeaderValue, AUTHORIZATION}; +use warp::{reject, Filter, Rejection}; +use thiserror::Error; +use anyhow::*; + +const BEARER: &str = "Bearer "; +const PUBLIC_KEY_PEM: &str = "-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4nU0G4WjkmcQUx0hq6LQ +uV5Q+ACmUFL/OjoYMDwC/O/6pCd1UZgCfgHN2xEffDPznzcTn8OiFRxr4oWyBiny +rUpnY4mhy0SQUwoeCw7YkcHAyhCjNT74aR/ohX0MCj0qRRdbt5ZQXM/GC3HJuXE1 +ptSuhFgQxziItamn8maoJ6JUSVEXVO1NOrrjoM3r7Q+BK2B+sX4/bLZ+VG5g1q2n +EbFdTHS6pHqtZNHQndTmEKwRfh0RYtzEzOXuO6e1gQY42Tujkof40dhGCIU7TeIG +GHwdFxy1niLkXwtHNjV7lnIOkTbx6+sSPamRfQAlZqUWM2Lf5o+7h3qWP3ENB138 +sQIDAQAB +-----END PUBLIC KEY-----"; + +// const private_key_pem: &str = "-----BEGIN RSA PRIVATE KEY----- +// MIIEpAIBAAKCAQEA4nU0G4WjkmcQUx0hq6LQuV5Q+ACmUFL/OjoYMDwC/O/6pCd1 +// UZgCfgHN2xEffDPznzcTn8OiFRxr4oWyBinyrUpnY4mhy0SQUwoeCw7YkcHAyhCj +// NT74aR/ohX0MCj0qRRdbt5ZQXM/GC3HJuXE1ptSuhFgQxziItamn8maoJ6JUSVEX +// VO1NOrrjoM3r7Q+BK2B+sX4/bLZ+VG5g1q2nEbFdTHS6pHqtZNHQndTmEKwRfh0R +// YtzEzOXuO6e1gQY42Tujkof40dhGCIU7TeIGGHwdFxy1niLkXwtHNjV7lnIOkTbx +// 6+sSPamRfQAlZqUWM2Lf5o+7h3qWP3ENB138sQIDAQABAoIBAD23nYTmrganag6M +// wPFrBSGP79c3Lhx0EjUHQjJbGKFgsdltG48qM3ut+DF9ACy0Z+/7bbC7+39vaIOq +// 1jLR2d6aiYTaLKseO4s2FawD1sgamvU3BZPsXn0gAhnnU5Gyy8Nas1dccvhoc9wI +// neaZUPrvucQ90AzLfo6r9yacDbYHB1lOyomApUvpJxOgHISGEtc9qGPDrdH19aF0 +// 8fCv2bbQRh+TChgN3IB0o5w0wXaI7YAyAouAv/AzHCoEMpt7OGjFTkjh/ujlPL9O +// +FLuJNsQRHDN0gJo2pcvwGwDCsioMixQ9bZ7ZrUu2BNpEQygyeSbj9ZI1iRvhosO +// JU3rwEECgYEA9MppTYA6A9WQbCCwPH1QMpUAmPNVSWVhUVag4lGOEhdCDRcz9ook +// DohQMKctiEB1luKuvDokxo0uMOfMO9/YwjsRB7qjQip7Th1zMJIjD+A+juLzHK4r +// /RiRtWYGAnF8mptDvE+93JsPb3C/lQLvIhio5GQYWBqPJu6SpeosIskCgYEA7NPi +// Gbffzr2UQhW8BNKmctEEh8yFRVojFo3wwwWxSNUVXGSmSm31CL+Q8h817R+2OkPV +// 1ZMUOBU4UJiqFt28kIvTDFqbAJlJQGCpY2mY7OLQiD2A+TVLcFrHmoCaPfCAK1Qd +// hQ0PmFK7Mf8qClpA3E5chop/WfKQfiu46sZv1qkCgYAhGdXPcw1lQ1W6KVlrdI6J +// qHhiNlVMDXdxZkNvFxQdAiQeXQrbxaZGiMw/J/wSNpUwCAsUzM/4QVMDrfSCDCzl +// ZtNQtj4pTlFKKNVQthIjrXEIJUw2jp7IJLBfVSJu5iWxSlmId0f3MsiNizN81N69 +// P5Rm/doE3+KHoy8VXGsHcQKBgQCkNh62enqjHWypjex6450qS6f6iWN3PRLLVsw0 +// TcQpniZblCaBwVCAKmRUnjOEIdL2/4ZLutnwMTaFG/YEOOfAylMiY8jKV38lNmD9 +// X4D78CFr9klxgvS2CRwSE03f2NzmLkLxuKaxldvaxPTfjMkgeO1LFMlNExYBhkuH +// 7uQpUQKBgQCKX6qMNh2gSdgG7qyxfTFZ4y5EGOBoKe/dE+IcVF3Vnh6DZVbCAbBL +// 5EdFWZSrCnDjA4xiKW55mwp95Ud9EZsZAb13L8V9t82eK+UDBoWlb7VRNYpda/x1 +// 5/i4qQJ28x2UNJDStpYFpnp4Ba1lvXjKngIbDPkjU+hbBJ+BNGAIeg== +// -----END RSA PRIVATE KEY-----"; + +/// sub: Subject, user identifier +/// exp: Expiration date, Unix Time, epoch +/// puk: Public Key? Not 100% on this +#[derive(Debug, Serialize, Deserialize)] +struct Claims { + sub: String, + exp: usize, + puk: String, +} + +// #[derive(Error, Debug)] +// pub enum Nope { +// #[error("Invalid header")] +// InvalidHeader { +// expected: String, +// found: String, +// }, +// } + +pub fn with_auth( + db: Db, + t: Transaction, +) -> impl Filter + Clone { + headers_cloned() + .map(move |headers: HeaderMap| (db.clone(), headers)) + .and_then(authorize) +} + +impl warp::reject::Reject for Nope {} + +async fn authorize((db, headers): (Db, HeaderMap)) -> Result { + match jwt_from_header(&headers) { + Ok(jwt) => { + let decoded = decode::( + &jwt, + // TODO: what key are we using here? pass db/pw store here to get the claimant's + // public key <10-04-21, yigit> // + &DecodingKey::from_rsa_pem(PUBLIC_KEY_PEM.as_bytes()).unwrap(), + &Validation::new(Algorithm::HS512), + ) + .map_err(|_| reject::custom(Error::JWTTokenError)) + .unwrap(); + + Ok(decoded.claims.puk) + } + Err(e) => return Err(anyhow!("missing!")); + } +} + +fn jwt_from_header(headers: &HeaderMap) -> Result { + let header = match headers.get(AUTHORIZATION) { + Some(v) => v, + None => return Err(Error::NoAuthHeaderError), + }; + let auth_header = match std::str::from_utf8(header.as_bytes()) { + Ok(v) => v, + Err(_) => return Err(Error::NoAuthHeaderError), + }; + if !auth_header.starts_with(BEARER) { + return Err(Error::InvalidAuthHeaderError); + } + Ok(auth_header.trim_start_matches(BEARER).to_owned()) +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..0db26c4 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,63 @@ +use serde::Serialize; +use std::convert::Infallible; +use thiserror::Error; +use warp::{http::StatusCode, Rejection, Reply}; + +#[derive(Error, Debug)] +pub enum Error { + // #[error("wrong credentials")] + // WrongCredentialsError, + #[error("jwt token not valid")] + JWTTokenError, + // #[error("jwt token creation error")] + // JWTTokenCreationError, + #[error("no auth header")] + NoAuthHeaderError, + #[error("invalid auth header")] + InvalidAuthHeaderError, + // #[error("no permission")] + // NoPermissionError, +} + +#[derive(Serialize, Debug)] +struct ErrorResponse { + message: String, + status: String, +} + +impl warp::reject::Reject for Error {} + +pub async fn handle_rejection(err: Rejection) -> std::result::Result { + let (code, message) = if err.is_not_found() { + (StatusCode::NOT_FOUND, "Not Found".to_string()) + } else if let Some(e) = err.find::() { + match e { + // Error::WrongCredentialsError => (StatusCode::FORBIDDEN, e.to_string()), + // Error::NoPermissionError => (StatusCode::UNAUTHORIZED, e.to_string()), + Error::JWTTokenError => (StatusCode::UNAUTHORIZED, e.to_string()), + // Error::JWTTokenCreationError => ( + // StatusCode::INTERNAL_SERVER_ERROR, + // "Internal Server Error".to_string(), + // ), + _ => (StatusCode::BAD_REQUEST, e.to_string()), + } + } else if err.find::().is_some() { + ( + StatusCode::METHOD_NOT_ALLOWED, + "Method Not Allowed".to_string(), + ) + } else { + eprintln!("unhandled error: {:?}", err); + ( + StatusCode::INTERNAL_SERVER_ERROR, + "Internal Server Error".to_string(), + ) + }; + + let json = warp::reply::json(&ErrorResponse { + status: code.to_string(), + message, + }); + + Ok(warp::reply::with_status(json, code)) +} diff --git a/src/handlers.rs b/src/handlers.rs index 856970d..256e72a 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -58,6 +58,24 @@ pub async fn propose_transaction( Ok(StatusCode::CREATED) } +/// POST /transaction, authenticated +/// The transaction arrived in this method has been authored by the public key in the source +pub async fn propose_authenticated_transaction( + pubkey: String, + new_transaction: Transaction, + db: Db, +) -> Result { + debug!("new transaction request {:?}", new_transaction); + + // let mut transactions = db.lock().await; + let mut transactions = db.pending_transactions.write(); + + transactions.insert(new_transaction.source.to_owned(), new_transaction); + + Ok(StatusCode::CREATED) +} + + /// POST /block /// Proposes a new block for the next round /// Can reject the block diff --git a/src/main.rs b/src/main.rs index 7ef2597..91f6757 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,8 @@ mod custom_filters; mod handlers; mod routes; mod schema; +mod auth; +mod error; // mod validators; #[tokio::main] diff --git a/src/routes.rs b/src/routes.rs index 95138e6..499ba35 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,8 +1,9 @@ use warp::{Filter, Rejection, Reply}; +use crate::auth::with_auth; use crate::custom_filters; use crate::handlers; -use crate::schema::Db; +use crate::schema::{Db, Transaction}; /// Root, all routes combined pub fn consensus_routes(db: Db) -> impl Filter + Clone { @@ -14,7 +15,8 @@ pub fn consensus_routes(db: Db) -> impl Filter impl Filter + Clone { - warp::path!("transaction") + warp::path("transaction") + .and(warp::path::end()) .and(warp::get()) .and(custom_filters::with_db(db)) .and_then(handlers::list_transactions) @@ -30,13 +32,43 @@ pub fn block_list(db: Db) -> impl Filter impl Filter + Clone { - warp::path!("transaction") + warp::path("transaction") + .and(warp::path::end()) .and(warp::post()) .and(custom_filters::transaction_json_body()) .and(custom_filters::with_db(db)) .and_then(handlers::propose_transaction) } +/// POST /transaction warp route with authentication +pub fn authenticated_transaction_propose( + db: Db, +) -> impl Filter + Clone { + warp::path("transaction") + .and(warp::path::end()) + .and(warp::post()) + .and(custom_filters::transaction_json_body()) + .map(|t: Transaction| { + with_auth(db.clone(), t) + }) + .untuple_one() + .and(custom_filters::transaction_json_body()) + .and(custom_filters::with_db(db)) + .and_then(handlers::propose_authenticated_transaction) + + // .and(custom_filters::transaction_json_body()) + // // TODO: you might have to restore this + // // what we're trying to do is knowing which public key to use to decode the jwt in the + // // header of the request, we will either request it through a header (ugly, ugh) or get it + // // from json (then how do we chain these ugh) or we can just validate/check (move the + // // header/jwt logic to propose_transaction but that doesn't feel right either + // // good luck <10-04-21, yigit> // + // .map(|t: Transaction| with_auth(db.clone(), t)) + // .and(custom_filters::transaction_json_body()) + // .and(custom_filters::with_db(db)) + // .and_then(handlers::propose_transaction) +} + /// POST /block warp route pub fn block_propose(db: Db) -> impl Filter + Clone { warp::path!("block") diff --git a/src/schema.rs b/src/schema.rs index 556e625..c4917ab 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -29,6 +29,8 @@ pub struct Db { pub blockchain: Arc>>, // every proposer can have _one_ pending transaction, a way to enforce this, String is proposer identifier pub pending_transactions: Arc>>, + // this was bound to happen eventually + pub users: Arc>>, } impl Db { @@ -36,12 +38,15 @@ impl Db { Db { blockchain: Arc::new(RwLock::new(Vec::new())), pending_transactions: Arc::new(RwLock::new(HashMap::new())), + users: Arc::new(RwLock::new(HashMap::new())), } } } -/// A transaction between `source` and `target` that moves `amount` -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +/// A transaction between `source` and `target` that moves `amount` Note: +/// https://serde.rs/container-attrs.html might be valueable to normalize the serialize/deserialize +/// conventions as these will be hashed +#[derive(Serialize, Deserialize, Debug)] pub struct Transaction { pub source: String, pub target: String, @@ -65,5 +70,10 @@ pub struct Block { pub hash: String, // future proof'd baby } +#[derive(Serialize, Deserialize, Debug)] +pub struct User { + username: String, + token: String +} // TODO: write schema tests using the original repo <09-04-21, yigit> // -- cgit v1.2.3-70-g09d2