From 5e77c7755963794cb03209a8a2a6bcdb03d30b1e Mon Sep 17 00:00:00 2001 From: trivernis Date: Fri, 11 Sep 2020 18:24:40 +0200 Subject: [PATCH] Add login route Signed-off-by: trivernis --- Cargo.lock | 746 ++++++++++++++++++++++++++++++++++---- Cargo.toml | 7 +- src/database/tokens.rs | 15 +- src/database/users.rs | 56 +-- src/lib.rs | 3 + src/main.rs | 10 + src/server/http_server.rs | 86 +++++ src/server/messages.rs | 7 + src/server/mod.rs | 1 + src/utils/error.rs | 4 +- src/utils/mod.rs | 11 + 11 files changed, 839 insertions(+), 107 deletions(-) create mode 100644 src/server/http_server.rs diff --git a/Cargo.lock b/Cargo.lock index bbef3f8..6210156 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "aho-corasick" version = "0.7.13" @@ -9,6 +15,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "ascii" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" + [[package]] name = "async-channel" version = "1.4.2" @@ -79,7 +103,7 @@ dependencies = [ "futures-io", "futures-lite", "kv-log-macro", - "log", + "log 0.4.11", "memchr", "num_cpus", "once_cell", @@ -123,24 +147,63 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +dependencies = [ + "byteorder", + "safemem", +] + [[package]] name = "base64" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "bcrypt" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2cab630912253fb9dc92c0e2fabd0a7b51f5a5a4007177cfa31e517015b7204" +dependencies = [ + "base64 0.12.3", + "blowfish", + "byteorder", + "getrandom", +] + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "blake2b_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -150,6 +213,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-cipher" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80" +dependencies = [ + "generic-array", +] + [[package]] name = "blocking" version = "0.5.2" @@ -163,6 +235,47 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "blowfish" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f06850ba969bc59388b2cc0a4f186fc6d9d37208863b15b84ae3866ac90ac06" +dependencies = [ + "block-cipher", + "byteorder", + "opaque-debug", +] + +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + [[package]] name = "build_const" version = "0.2.1" @@ -205,6 +318,32 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "chrono" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" +dependencies = [ + "num-integer", + "num-traits", + "time", +] + +[[package]] +name = "chunked_transfer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + [[package]] name = "cloudabi" version = "0.1.0" @@ -247,6 +386,12 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "cpuid-bool" version = "0.1.2" @@ -262,13 +407,22 @@ dependencies = [ "build_const", ] +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-utils" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg", + "autocfg 1.0.1", "cfg-if", "lazy_static", ] @@ -284,13 +438,14 @@ dependencies = [ ] [[package]] -name = "crypto-mac" -version = "0.9.1" +name = "deflate" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" dependencies = [ - "generic-array", - "subtle", + "adler32", + "byteorder", + "gzip-header", ] [[package]] @@ -302,6 +457,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -322,7 +488,7 @@ checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ "atty", "humantime", - "log", + "log 0.4.11", "regex", "termcolor", ] @@ -345,24 +511,39 @@ version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c85295147490b8fcf2ea3d104080a105a8b2c63f9c319e82c02d8e952388919" +[[package]] +name = "filetime" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + [[package]] name = "flotte-user-management" version = "0.1.0" dependencies = [ + "bcrypt", "byteorder", "colored", "crossbeam-utils", "dotenv", "env_logger", - "log", + "log 0.4.11", + "mime 0.3.16", "msgrpc", "postgres", - "rand", + "rand 0.7.3", "redis", "rmp", "rmp-serde", - "scrypt", + "rouille", "serde", + "serde_json", "serde_postgres", "zeroize", ] @@ -373,6 +554,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -506,7 +693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", - "version_check", + "version_check 0.9.2", ] [[package]] @@ -517,7 +704,16 @@ checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gzip-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0131feb3d3bb2a5a238d8a4d09f6353b7ebfdc52e77bccbf4ea6eaa751dde639" +dependencies = [ + "crc32fast", ] [[package]] @@ -535,19 +731,15 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "crypto-mac 0.8.0", + "crypto-mac", "digest", ] [[package]] -name = "hmac" -version = "0.9.0" +name = "httparse" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deae6d9dbb35ec2c502d62b8f7b1c000a0822c3b0794ba36b3149c0a1c840dff" -dependencies = [ - "crypto-mac 0.9.1", - "digest", -] +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" [[package]] name = "humantime" @@ -558,6 +750,17 @@ dependencies = [ "quick-error", ] +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.2.0" @@ -615,7 +818,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" dependencies = [ - "log", + "log 0.4.11", ] [[package]] @@ -639,6 +842,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +dependencies = [ + "log 0.4.11", +] + [[package]] name = "log" version = "0.4.11" @@ -666,6 +878,33 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" +dependencies = [ + "log 0.3.9", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "1.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216929a5ee4dd316b1702eedf5e74548c123d370f47841ceaac38ca154690ca3" +dependencies = [ + "mime 0.2.6", + "phf 0.7.24", + "phf_codegen", + "unicase", +] + [[package]] name = "mio" version = "0.6.22" @@ -678,7 +917,7 @@ dependencies = [ "iovec", "kernel32-sys", "libc", - "log", + "log 0.4.11", "miow", "net2", "slab", @@ -715,12 +954,30 @@ dependencies = [ "byteorder", "crc", "crossbeam-utils", - "log", + "log 0.4.11", "rmp", "rmp-serde", "serde", ] +[[package]] +name = "multipart" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adba94490a79baf2d6a23eac897157047008272fa3eecb3373ae6377b91eca28" +dependencies = [ + "buf_redux", + "httparse", + "log 0.4.11", + "mime 0.2.6", + "mime_guess", + "quick-error", + "rand 0.4.6", + "safemem", + "tempdir", + "twoway", +] + [[package]] name = "multitask" version = "0.2.0" @@ -743,13 +1000,23 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg 1.0.1", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ - "autocfg", + "autocfg 1.0.1", ] [[package]] @@ -804,7 +1071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ "cfg-if", - "cloudabi", + "cloudabi 0.1.0", "instant", "libc", "redox_syscall", @@ -813,13 +1080,10 @@ dependencies = [ ] [[package]] -name = "pbkdf2" -version = "0.5.0" +name = "percent-encoding" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170d73bf11f39b4ce1809aabc95bf5c33564cdc16fc3200ddda17a5f6e5e48b" -dependencies = [ - "crypto-mac 0.9.1", -] +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" [[package]] name = "percent-encoding" @@ -827,13 +1091,52 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "phf" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +dependencies = [ + "phf_shared 0.7.24", +] + [[package]] name = "phf" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_shared", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +dependencies = [ + "phf_generator", + "phf_shared 0.7.24", +] + +[[package]] +name = "phf_generator" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +dependencies = [ + "phf_shared 0.7.24", + "rand 0.6.5", +] + +[[package]] +name = "phf_shared" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +dependencies = [ + "siphasher 0.2.3", + "unicase", ] [[package]] @@ -842,7 +1145,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" dependencies = [ - "siphasher", + "siphasher 0.3.3", ] [[package]] @@ -885,7 +1188,7 @@ checksum = "8fffa183f6bd5f1a8a3e1f60ce2f8d5621e350eed84a62d6daaa5b9d1aaf6fbd" dependencies = [ "cfg-if", "libc", - "log", + "log 0.4.11", "wepoll-sys-stjepang", "winapi 0.3.9", ] @@ -899,7 +1202,7 @@ dependencies = [ "bytes", "fallible-iterator", "futures", - "log", + "log 0.4.11", "tokio", "tokio-postgres", ] @@ -910,14 +1213,14 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81c5b25980f9a9b5ad36e9cdc855530575396d8a57f67e14691a2440ed0d9a90" dependencies = [ - "base64", + "base64 0.12.3", "byteorder", "bytes", "fallible-iterator", - "hmac 0.8.1", + "hmac", "md5", "memchr", - "rand", + "rand 0.7.3", "sha2", "stringprep", ] @@ -975,6 +1278,51 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi 0.3.9", +] + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +dependencies = [ + "cloudabi 0.0.3", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi 0.3.9", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi 0.3.9", +] + [[package]] name = "rand" version = "0.7.3" @@ -983,9 +1331,19 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", ] [[package]] @@ -995,9 +1353,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -1007,13 +1380,84 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi 0.3.9", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi 0.0.3", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi 0.3.9", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", ] [[package]] @@ -1029,12 +1473,12 @@ dependencies = [ "dtoa", "futures-util", "itoa", - "percent-encoding", + "percent-encoding 2.1.0", "pin-project-lite", "sha1", "tokio", "tokio-util", - "url", + "url 2.1.1", ] [[package]] @@ -1043,6 +1487,17 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + [[package]] name = "regex" version = "1.3.9" @@ -1061,6 +1516,15 @@ version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "rmp" version = "0.8.9" @@ -1082,6 +1546,55 @@ dependencies = [ "serde", ] +[[package]] +name = "rouille" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112568052ec17fa26c6c11c40acbb30d3ad244bf3d6da0be181f5e7e42e5004f" +dependencies = [ + "base64 0.9.3", + "brotli2", + "chrono", + "deflate", + "filetime", + "multipart", + "num_cpus", + "rand 0.5.6", + "serde", + "serde_derive", + "serde_json", + "sha1", + "term", + "threadpool", + "time", + "tiny_http", + "url 1.7.2", +] + +[[package]] +name = "rust-argon2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" +dependencies = [ + "base64 0.12.3", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + [[package]] name = "scoped-tls" version = "1.0.0" @@ -1094,21 +1607,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scrypt" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3437654bbbe34054a268b3859fe41f871215069b39f0aef78808d85c37100696" -dependencies = [ - "base64", - "hmac 0.9.0", - "pbkdf2", - "rand", - "rand_core", - "sha2", - "subtle", -] - [[package]] name = "serde" version = "1.0.115" @@ -1129,6 +1627,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_postgres" version = "0.2.0" @@ -1158,6 +1667,12 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "siphasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" + [[package]] name = "siphasher" version = "0.3.3" @@ -1227,6 +1742,27 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi 0.3.9", +] + [[package]] name = "termcolor" version = "1.1.0" @@ -1245,6 +1781,39 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi 0.3.9", +] + +[[package]] +name = "tiny_http" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1661fa0a44c95d01604bd05c66732a446c657efb62b5164a7a083a3b552b4951" +dependencies = [ + "ascii", + "chrono", + "chunked_transfer", + "log 0.4.11", + "url 1.7.2", +] + [[package]] name = "tinyvec" version = "0.3.4" @@ -1281,10 +1850,10 @@ dependencies = [ "bytes", "fallible-iterator", "futures", - "log", + "log 0.4.11", "parking_lot", - "percent-encoding", - "phf", + "percent-encoding 2.1.0", + "phf 0.8.0", "pin-project-lite", "postgres-protocol", "postgres-types", @@ -1301,17 +1870,35 @@ dependencies = [ "bytes", "futures-core", "futures-sink", - "log", + "log 0.4.11", "pin-project-lite", "tokio", ] +[[package]] +name = "twoway" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" +dependencies = [ + "memchr", +] + [[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +dependencies = [ + "version_check 0.1.5", +] + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -1336,15 +1923,26 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +dependencies = [ + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", +] + [[package]] name = "url" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ - "idna", + "idna 0.2.0", "matches", - "percent-encoding", + "percent-encoding 2.1.0", ] [[package]] @@ -1353,6 +1951,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb18268690309760d59ee1a9b21132c126ba384f374c59a94db4bc03adeb561" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" + [[package]] name = "version_check" version = "0.9.2" @@ -1371,6 +1975,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasm-bindgen" version = "0.2.68" @@ -1389,7 +1999,7 @@ checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" dependencies = [ "bumpalo", "lazy_static", - "log", + "log 0.4.11", "proc-macro2", "quote", "syn", diff --git a/Cargo.toml b/Cargo.toml index 05c1fdb..68b7bfe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ dotenv = "0.15.0" redis = "0.17.0" serde = {version = "1.0.115", features = ["serde_derive"]} rand = "0.7.3" -scrypt = "0.4.1" +bcrypt = "0.8.2" zeroize = {version = "1.1.0", features = ["zeroize_derive"]} byteorder = "1.3.4" rmp-serde = "0.14.4" @@ -22,4 +22,7 @@ rmp = "0.8.9" log = "0.4.11" env_logger = "0.7.1" colored = "2.0.0" -crossbeam-utils = "0.7.2" \ No newline at end of file +crossbeam-utils = "0.7.2" +mime = "0.3.16" +serde_json = "1.0.57" +rouille = "3.0.0" \ No newline at end of file diff --git a/src/database/tokens.rs b/src/database/tokens.rs index b8c97b3..5bf64af 100644 --- a/src/database/tokens.rs +++ b/src/database/tokens.rs @@ -3,12 +3,13 @@ use crate::utils::create_user_token; use crate::utils::error::RedisConnection; use byteorder::{BigEndian, ByteOrder}; use redis::{ErrorKind, RedisError, RedisResult}; +use serde::Serialize; use zeroize::Zeroize; -const REQUEST_TOKEN_EXPIRE_SECONDS: usize = 60 * 10; -const REFRESH_TOKEN_EXPIRE_SECONDS: usize = 60 * 60 * 24; +const REQUEST_TOKEN_EXPIRE_SECONDS: i32 = 60 * 10; +const REFRESH_TOKEN_EXPIRE_SECONDS: i32 = 60 * 60 * 24; -#[derive(Clone, Debug, Zeroize)] +#[derive(Clone, Debug, Zeroize, Serialize)] #[zeroize(drop)] pub struct SessionTokens { pub request_token: [u8; 32], @@ -22,8 +23,8 @@ impl SessionTokens { Self { request_token: create_user_token(user_id), refresh_token: create_user_token(user_id), - request_ttl: -1, - refresh_ttl: -1, + request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS, + refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS, } } @@ -31,8 +32,8 @@ impl SessionTokens { Self { request_token, refresh_token, - request_ttl: -1, - refresh_ttl: -1, + request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS, + refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS, } } diff --git a/src/database/users.rs b/src/database/users.rs index 2abfff2..fb1e55f 100644 --- a/src/database/users.rs +++ b/src/database/users.rs @@ -3,9 +3,9 @@ use crate::database::tokens::SessionTokens; use crate::database::user_roles::UserRoles; use crate::database::{DatabaseResult, RedisConnection, Table}; use crate::utils::error::DBError; -use crate::utils::{create_salt, get_user_id_from_token, TOKEN_LENGTH}; +use crate::utils::{create_salt, get_user_id_from_token, hash_password, TOKEN_LENGTH}; + use postgres::Client; -use scrypt::ScryptParams; use std::sync::{Arc, Mutex}; use zeroize::{Zeroize, Zeroizing}; @@ -65,14 +65,8 @@ impl Users { return Err(DBError::RecordExists); } let salt = Zeroizing::new(create_salt()); - let mut pw_hash = Zeroizing::new([0u8; 32]); - scrypt::scrypt( - password.as_bytes(), - &*salt, - &ScryptParams::recommended(), - &mut *pw_hash, - ) - .map_err(|_| DBError::ScryptError)?; + let pw_hash = + hash_password(password.as_bytes(), &*salt).map_err(|e| DBError::GenericError(e))?; password.zeroize(); let row = connection.query_one(" INSERT INTO users (name, email, password_hash, salt) VALUES ($1, $2, $3, $4) RETURNING *; @@ -81,17 +75,25 @@ impl Users { Ok(UserRecord::from_ordered_row(&row)) } - pub fn create_token(&self, email: String, password: String) -> DatabaseResult { + pub fn create_get_tokens( + &self, + email: String, + password: String, + ) -> DatabaseResult { if self.validate_login(&email, password)? { let mut connection = self.database_connection.lock().unwrap(); let row = connection.query_one("SELECT id FROM users WHERE email = $1", &[&email])?; let id: i32 = row.get(0); let mut redis_connection = self.redis_connection.lock().unwrap(); - let tokens = SessionTokens::new(id); - tokens.store(&mut redis_connection)?; + if let Ok(tokens) = SessionTokens::retrieve(id, &mut redis_connection) { + Ok(tokens) + } else { + let tokens = SessionTokens::new(id); + tokens.store(&mut redis_connection)?; - Ok(tokens) + Ok(tokens) + } } else { Err(DBError::GenericError("Invalid password".to_string())) } @@ -140,22 +142,20 @@ impl Users { fn validate_login(&self, email: &String, password: String) -> DatabaseResult { let password = Zeroizing::new(password); let mut connection = self.database_connection.lock().unwrap(); - let row = connection.query_one( - "SELECT password_hash, salt FROM users WHERE email = $1", - &[&email], - )?; + let row = connection + .query_opt( + "SELECT password_hash, salt FROM users WHERE email = $1", + &[&email], + )? + .ok_or(DBError::GenericError(format!( + "No user with the email '{}' found", + &email + )))?; let original_pw_hash: Zeroizing> = Zeroizing::new(row.get(0)); let salt: Zeroizing> = Zeroizing::new(row.get(1)); - let mut pw_hash = Zeroizing::new([0u8; 32]); - - scrypt::scrypt( - password.as_bytes(), - &*salt, - &ScryptParams::recommended(), - &mut *pw_hash, - ) - .map_err(|_| DBError::ScryptError)?; + let pw_hash = + hash_password(password.as_bytes(), &*salt).map_err(|e| DBError::GenericError(e))?; - Ok(*pw_hash == *original_pw_hash.as_slice()) + Ok(pw_hash == *original_pw_hash.as_slice()) } } diff --git a/src/lib.rs b/src/lib.rs index 5c8e349..6496c66 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate rouille; + pub mod database; pub mod server; pub mod utils; diff --git a/src/main.rs b/src/main.rs index 2d46e51..41e2097 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use colored::Colorize; use crossbeam_utils::sync::WaitGroup; use env_logger::Env; use flotte_user_management::database::Database; +use flotte_user_management::server::http_server::UserHttpServer; use flotte_user_management::server::user_rpc::UserRpcServer; use log::Level; use std::thread; @@ -11,6 +12,7 @@ fn main() { let database = Database::new().unwrap(); database.init().unwrap(); let rpc_server = UserRpcServer::new(&database); + let http_server = UserHttpServer::new(&database); let wg = WaitGroup::new(); { let wg = WaitGroup::clone(&wg); @@ -19,6 +21,14 @@ fn main() { std::mem::drop(wg); }); } + { + let wg = WaitGroup::clone(&wg); + let http_server = http_server; + thread::spawn(move || { + http_server.start(); + std::mem::drop(wg); + }); + } wg.wait(); } diff --git a/src/server/http_server.rs b/src/server/http_server.rs new file mode 100644 index 0000000..f9ddccc --- /dev/null +++ b/src/server/http_server.rs @@ -0,0 +1,86 @@ +use crate::database::Database; +use crate::server::messages::LoginMessage; +use crate::utils::error::DBError; +use rouille::{Request, Response, Server}; +use serde::export::Formatter; +use std::error::Error; +use std::fmt::{self, Display}; +use std::io::Read; + +const LISTEN_ADDRESS: &str = "HTTP_SERVER_ADDRESS"; +const DEFAULT_LISTEN_ADDRESS: &str = "127.0.0.1:8080"; + +pub struct UserHttpServer { + database: Database, +} + +#[derive(Debug)] +pub struct HTTPError { + message: String, + code: usize, +} + +impl Display for HTTPError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.message) + } +} +impl Error for HTTPError {} + +impl From for HTTPError { + fn from(other: DBError) -> Self { + Self { + message: other.to_string(), + code: 400, + } + } +} + +impl HTTPError { + pub fn new(message: String, code: usize) -> Self { + Self { message, code } + } +} + +type HTTPResult = Result; + +impl UserHttpServer { + pub fn new(database: &Database) -> Self { + Self { + database: Database::clone(database), + } + } + + pub fn start(&self) { + let listen_address = + dotenv::var(LISTEN_ADDRESS).unwrap_or(DEFAULT_LISTEN_ADDRESS.to_string()); + let database = Database::clone(&self.database); + let server = Server::new(listen_address, move |request| { + router!(request, + (POST) (/login) => { + Self::login(&database, request).unwrap_or_else(|e|Response::text(e.to_string())) + }, + _ => Response::empty_404() + ) + }) + .unwrap(); + server.run() + } + + fn login(database: &Database, request: &Request) -> HTTPResult { + if let Some(mut data) = request.data() { + let mut data_string = String::new(); + data.read_to_string(&mut data_string) + .map_err(|_| HTTPError::new("Failed to read request data".to_string(), 500))?; + let login_request: LoginMessage = serde_json::from_str(data_string.as_str()) + .map_err(|e| HTTPError::new(e.to_string(), 400))?; + let tokens = database + .users + .create_get_tokens(login_request.email, login_request.password)?; + + Ok(Response::json(&tokens)) + } else { + Err(HTTPError::new("Missing Request Data".to_string(), 400)) + } + } +} diff --git a/src/server/messages.rs b/src/server/messages.rs index 3854c4d..3c719cb 100644 --- a/src/server/messages.rs +++ b/src/server/messages.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; use std::error::Error; use std::fmt; use std::fmt::Display; +use zeroize::Zeroize; #[derive(Deserialize)] pub struct TokenRequest { @@ -74,3 +75,9 @@ pub struct CreateRoleRequest { pub struct CreatePermissionsRequest { pub permissions: Vec, } + +#[derive(Deserialize, Zeroize)] +pub struct LoginMessage { + pub email: String, + pub password: String, +} diff --git a/src/server/mod.rs b/src/server/mod.rs index ec75acc..7044df8 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,3 +1,4 @@ +pub mod http_server; pub mod messages; pub mod rpc_methods; pub mod user_rpc; diff --git a/src/utils/error.rs b/src/utils/error.rs index 71590d2..2d01a16 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -8,7 +8,7 @@ pub enum DBError { Redis(RedisError), Postgres(PostgresError), RecordExists, - ScryptError, + BCryptError, DeserializeError(serde_postgres::DeError), GenericError(String), } @@ -29,7 +29,7 @@ impl DBError { DBError::Postgres(p) => p.to_string(), DBError::Redis(r) => r.to_string(), DBError::DeserializeError(de) => de.to_string(), - DBError::ScryptError => "sCrypt Hash creation error".to_string(), + DBError::BCryptError => "BCrypt Hash creation error".to_string(), } } } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 22f8cc9..ddaf482 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,5 +1,7 @@ +use bcrypt::DEFAULT_COST; use byteorder::{BigEndian, ByteOrder}; use rand::Rng; +use std::panic; pub mod error; @@ -26,3 +28,12 @@ pub fn create_user_token(user_id: i32) -> [u8; TOKEN_LENGTH] { pub fn get_user_id_from_token(token: &[u8]) -> i32 { BigEndian::read_i32(token) } + +pub fn hash_password(password: &[u8], salt: &[u8]) -> Result<[u8; 24], String> { + panic::catch_unwind(|| { + let mut pw_hash = [0u8; 24]; + bcrypt::bcrypt(DEFAULT_COST, salt, password, &mut pw_hash); + Ok(pw_hash) + }) + .map_err(|_| "Hashing failed".to_string())? +}