From 81aa4788b45de1c5386e25b20c9a3e518852e7a8 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 12 Jun 2023 04:10:10 +0200 Subject: [PATCH] David/60 add basic email verification (#119) * added logic to check e-mails thru SMPT server, very basic, no validation e-mails etc. * added rpc key logic to use db numbers instead of UUIDs * Revert "added rpc key logic to use db numbers instead of UUIDs" This reverts commit 056771d02725f90ed5f1745b0372e13e630a19ac. --- Cargo.lock | 439 ++++++++++++++++++++++++++- web3_proxy/Cargo.toml | 1 + web3_proxy/src/frontend/users/mod.rs | 22 +- 3 files changed, 455 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index def87e87..2bb2c094 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,6 +175,23 @@ dependencies = [ "term", ] +[[package]] +name = "ascii_utils" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-compression" version = "0.4.0" @@ -188,6 +205,35 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + [[package]] name = "async-io" version = "1.13.0" @@ -204,7 +250,7 @@ dependencies = [ "polling", "rustix", "slab", - "socket2", + "socket2 0.4.9", "waker-fn", ] @@ -217,6 +263,113 @@ dependencies = [ "event-listener", ] +[[package]] +name = "async-native-tls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d57d4cec3c647232e1094dc013546c0b33ce785d8aeb251e1f20dfaf8a9a13fe" +dependencies = [ + "native-tls", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "async-process" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +dependencies = [ + "async-io", + "async-lock", + "autocfg", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "signal-hook", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-recursion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "async-smtp" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da21e1dd19fbad3e095ad519fb1558ab77fd82e5c4778dca8f9be0464589e1e" +dependencies = [ + "async-native-tls", + "async-trait", + "base64 0.13.1", + "bufstream", + "fast-socks5", + "futures", + "hostname", + "log", + "nom", + "pin-project", + "pin-utils", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "tokio", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-std-resolver" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2f8a4a203be3325981310ab243a28e6e4ea55b6519bffce05d41ab60e09ad8" +dependencies = [ + "async-std", + "async-trait", + "futures-io", + "futures-util", + "pin-utils", + "socket2 0.4.9", + "trust-dns-resolver", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -239,6 +392,12 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + [[package]] name = "async-trait" version = "0.1.68" @@ -279,6 +438,12 @@ dependencies = [ "critical-section", ] +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "atty" version = "0.2.14" @@ -529,6 +694,21 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "borsh" version = "0.10.3" @@ -583,6 +763,12 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "bufstream" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" + [[package]] name = "bumpalo" version = "3.13.0" @@ -725,6 +911,28 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "check-if-email-exists" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bce0a060f3c32a2a609ed1ca38d2d8afdbfd03dc87de8d29124da6e09dfe2cec" +dependencies = [ + "async-native-tls", + "async-recursion", + "async-smtp", + "async-std", + "async-std-resolver", + "log", + "mailchecker", + "rand", + "reacher-fast-socks5", + "regex", + "reqwest", + "serde", + "serde_json", + "trust-dns-proto", +] + [[package]] name = "chrono" version = "0.4.26" @@ -1568,6 +1776,18 @@ dependencies = [ "uuid 1.3.3", ] +[[package]] +name = "enum-as-inner" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "env_logger" version = "0.10.0" @@ -1955,6 +2175,28 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fast-socks5" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961ce1761191c157145a8c9f0c3ceabecd3a729d65c9a8d443674eaee3420f7e" +dependencies = [ + "anyhow", + "log", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "fast_chemail" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" +dependencies = [ + "ascii_utils", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -2624,7 +2866,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -2692,6 +2934,17 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.4.0" @@ -2860,6 +3113,18 @@ dependencies = [ "libc", ] +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.3", + "widestring", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + [[package]] name = "ipnet" version = "2.7.2" @@ -2957,6 +3222,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lalrpop" version = "0.19.12" @@ -3039,6 +3313,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -3072,6 +3352,18 @@ name = "log" version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +dependencies = [ + "value-bag", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] [[package]] name = "mach2" @@ -3082,6 +3374,16 @@ dependencies = [ "libc", ] +[[package]] +name = "mailchecker" +version = "5.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c64fa7af9860896bdfe496f323ac278f256006fd248dd7730e37c5faa648b05" +dependencies = [ + "fast_chemail", + "once_cell", +] + [[package]] name = "match_cfg" version = "0.1.0" @@ -3106,6 +3408,12 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + [[package]] name = "matchit" version = "0.7.0" @@ -4204,6 +4512,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.28" @@ -4335,6 +4649,19 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "reacher-fast-socks5" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e0ee4dd08849e48b878598d7a8074284147ad924fe066c0923caf7e104cd12" +dependencies = [ + "anyhow", + "log", + "thiserror", + "tokio", + "tokio-stream", +] + [[package]] name = "redis" version = "0.23.0" @@ -4468,6 +4795,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.24.0", + "tokio-socks", "tokio-util", "tower-service", "url", @@ -4476,7 +4804,17 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots 0.22.6", - "winreg", + "winreg 0.10.1", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", ] [[package]] @@ -5469,6 +5807,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "solang-parser" version = "0.3.0" @@ -5949,7 +6297,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.4.9", "tokio-macros", "tracing", "windows-sys 0.48.0", @@ -6037,6 +6385,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -6086,7 +6446,7 @@ dependencies = [ "libc", "scoped-tls", "slab", - "socket2", + "socket2 0.4.9", "tokio", ] @@ -6346,6 +6706,50 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" +[[package]] +name = "trust-dns-proto" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "log", + "rand", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "parking_lot 0.12.1", + "resolv-conf", + "smallvec", + "thiserror", + "trust-dns-proto", +] + [[package]] name = "try-lock" version = "0.2.4" @@ -6531,7 +6935,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", - "idna", + "idna 0.4.0", "percent-encoding", "serde", ] @@ -6570,6 +6974,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e" + [[package]] name = "vcpkg" version = "0.2.15" @@ -6721,6 +7131,7 @@ dependencies = [ "axum-client-ip", "axum-macros", "base64 0.21.2", + "check-if-email-exists", "chrono", "console-subscriber", "counter", @@ -6818,6 +7229,12 @@ dependencies = [ "rustls-webpki", ] +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + [[package]] name = "winapi" version = "0.3.9" @@ -6999,6 +7416,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "ws_stream_wasm" version = "0.7.4" diff --git a/web3_proxy/Cargo.toml b/web3_proxy/Cargo.toml index 723bedf0..a72d74b1 100644 --- a/web3_proxy/Cargo.toml +++ b/web3_proxy/Cargo.toml @@ -43,6 +43,7 @@ async-trait = "0.1.68" axum = { version = "0.6.18", features = ["headers", "ws"] } axum-client-ip = "0.4.1" axum-macros = "0.3.7" +check-if-email-exists = "0.9.0" chrono = "0.4.26" console-subscriber = { version = "0.1.9", optional = true } counter = "0.5.7" diff --git a/web3_proxy/src/frontend/users/mod.rs b/web3_proxy/src/frontend/users/mod.rs index b3de0a3d..c5a4fa64 100644 --- a/web3_proxy/src/frontend/users/mod.rs +++ b/web3_proxy/src/frontend/users/mod.rs @@ -7,7 +7,7 @@ pub mod stats; pub mod subuser; use crate::app::Web3ProxyApp; -use crate::errors::{Web3ProxyErrorContext, Web3ProxyResponse}; +use crate::errors::{Web3ProxyError, Web3ProxyErrorContext, Web3ProxyResponse}; use axum::{ headers::{authorization::Bearer, Authorization}, @@ -15,6 +15,9 @@ use axum::{ Extension, Json, TypedHeader, }; use axum_macros::debug_handler; +use check_if_email_exists::{ + check_email, CheckEmailInput, CheckEmailInputProxy, CheckEmailOutput, Reachable, +}; use entities; use entities::user; use migration::sea_orm::{self, ActiveModelTrait}; @@ -59,6 +62,23 @@ pub async fn user_post( if x.is_empty() { user.email = sea_orm::Set(None); } else { + // Make a quick check if the e-mail provide is active + let check_email_input = CheckEmailInput::new(x.clone()); + // Verify this input, using async/await syntax. + let result = check_email(&check_email_input).await; + match result.is_reachable { + Reachable::Invalid => { + return Err(Web3ProxyError::BadRequest( + "The e-mail address you provided seems invalid".into(), + )); + } + // Let's be very chill about the validity of e-mails, and only error if the Syntax / SMPT / MX does not work + // Reachable::Safe => {} + // Reachable::Unknown => {} + // Reachable::Risky => {} + _ => {} + } + // TODO: do some basic validation // TODO: don't set immediatly, send a confirmation email first // TODO: compare first? or is sea orm smart enough to do that for us?