diff options
author | Colin Reeder <vpzomtrrfrt@gmail.com> | 2020-09-25 12:05:01 -0600 |
---|---|---|
committer | Colin Reeder <vpzomtrrfrt@gmail.com> | 2020-09-25 12:05:30 -0600 |
commit | af3947530d06f63a48512892233852e67be60ec2 (patch) | |
tree | b11cffe674448fea613b2f495d0372326e66c789 | |
parent | 538dd61f902247e5a65bb33fdf449181f43e8f5f (diff) |
Initialize SMTP transport
-rw-r--r-- | Cargo.lock | 185 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 44 |
3 files changed, 229 insertions, 1 deletions
@@ -26,6 +26,21 @@ dependencies = [ ] [[package]] +name = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + +[[package]] +name = "arc-swap" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" + +[[package]] name = "arrayvec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -650,6 +665,17 @@ dependencies = [ ] [[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi 0.3.9", +] + +[[package]] name = "http" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -714,6 +740,24 @@ dependencies = [ ] [[package]] +name = "hyperx" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eae1ec4abdc4530fb001ebf585fd14e52ed17f0aacd3e13de497b71ed451750" +dependencies = [ + "base64", + "bytes", + "http", + "httparse", + "language-tags", + "log", + "mime", + "percent-encoding", + "time", + "unicase", +] + +[[package]] name = "idna" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -800,12 +844,46 @@ dependencies = [ ] [[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] +name = "lettre" +version = "0.10.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ef0e6a22631e37078148cff6ce1ef92984bdc2fbd2cb2cc804836db8196cc57" +dependencies = [ + "async-trait", + "base64", + "futures-io", + "futures-util", + "hostname", + "hyperx", + "idna", + "mime", + "native-tls", + "nom", + "once_cell", + "quoted_printable", + "r2d2", + "rand", + "regex", + "serde", + "serde_json", + "tokio", + "tokio-native-tls", + "uuid", +] + +[[package]] name = "lexical-core" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -875,6 +953,7 @@ dependencies = [ "hyper", "hyper-tls", "lazy_static", + "lettre", "mime", "openssl", "percent-encoding", @@ -897,6 +976,12 @@ dependencies = [ ] [[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] name = "matches" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -949,13 +1034,25 @@ dependencies = [ "kernel32-sys", "libc", "log", - "miow", + "miow 0.2.1", "net2", "slab", "winapi 0.2.8", ] [[package]] +name = "mio-named-pipes" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" +dependencies = [ + "log", + "mio", + "miow 0.3.5", + "winapi 0.3.9", +] + +[[package]] name = "mio-uds" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -979,6 +1076,16 @@ dependencies = [ ] [[package]] +name = "miow" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" +dependencies = [ + "socket2", + "winapi 0.3.9", +] + +[[package]] name = "native-tls" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1268,6 +1375,23 @@ dependencies = [ ] [[package]] +name = "quoted_printable" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b080c5db639b292ac79cbd34be0cfc5d36694768d8341109634d90b86930e2" + +[[package]] +name = "r2d2" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1315,6 +1439,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] +name = "regex" +version = "1.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +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" @@ -1406,6 +1548,15 @@ dependencies = [ ] [[package]] +name = "scheduled-thread-pool" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" +dependencies = [ + "parking_lot", +] + +[[package]] name = "scoped-tls" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1524,6 +1675,16 @@ dependencies = [ ] [[package]] +name = "signal-hook-registry" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" +dependencies = [ + "arc-swap", + "libc", +] + +[[package]] name = "siphasher" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1627,6 +1788,15 @@ dependencies = [ ] [[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] name = "time" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1662,11 +1832,14 @@ dependencies = [ "libc", "memchr", "mio", + "mio-named-pipes", "mio-uds", "num_cpus", "pin-project-lite", + "signal-hook-registry", "slab", "tokio-macros", + "winapi 0.3.9", ] [[package]] @@ -1681,6 +1854,16 @@ dependencies = [ ] [[package]] +name = "tokio-native-tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd608593a919a8e05a7d1fc6df885e40f6a88d3a70a3a7eff23ff27964eda069" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] name = "tokio-postgres" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -42,6 +42,7 @@ unic-langid = { version = "0.9.0", features = ["macros"] } activitystreams = "0.7.0-alpha.3" activitystreams-ext = "0.1.0-alpha.2" fast_chemail = "0.9.6" +lettre = { version = "0.10.0-alpha.2", features = ["tokio02", "tokio02-native-tls"] } [dev-dependencies] rand = "0.7.3" diff --git a/src/main.rs b/src/main.rs index c654fb5..73c739d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,6 +94,8 @@ pub type HttpClient = hyper::Client<hyper_tls::HttpsConnector<hyper::client::Htt pub struct BaseContext { pub db_pool: DbPool, + pub mailer: Option<lettre::AsyncSmtpTransport<lettre::Tokio02Connector>>, + pub mail_from: Option<lettre::Mailbox>, pub host_url_api: String, pub host_url_apub: BaseURL, pub http_client: HttpClient, @@ -795,12 +797,54 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { .try_into() .expect("HOST_URL_ACTIVITYPUB is not a valid base URL"); + let smtp_url: Option<url::Url> = match std::env::var("SMTP_URL") { + Ok(value) => Some(value.parse().expect("Failed to parse SMTP_URL")), + Err(std::env::VarError::NotPresent) => None, + Err(other) => Err(other).expect("Failed to parse SMTP_URL"), + }; + let mailer = match smtp_url { + None => None, + Some(url) => { + let host = url.host_str().expect("Missing host in SMTP_URL"); + let mut builder = match url.scheme() { + "smtp" => { + lettre::AsyncSmtpTransport::<lettre::Tokio02Connector>::builder_dangerous(host) + } + "smtps" => lettre::AsyncSmtpTransport::<lettre::Tokio02Connector>::relay(host) + .expect("Failed to initialize SMTP transport"), + _ => panic!("Unrecognized scheme for SMTP_URL"), + }; + + if url.username() != "" || url.password().is_some() { + builder = + builder.credentials(lettre::transport::smtp::authentication::Credentials::new( + url.username().to_owned(), + url.password().unwrap_or("").to_owned(), + )); + } + + Some(builder.build()) + } + }; + + let mail_from: Option<lettre::Mailbox> = match std::env::var("SMTP_FROM") { + Ok(value) => Some(value.parse().expect("Failed to parse SMTP_FROM")), + Err(std::env::VarError::NotPresent) => None, + Err(other) => Err(other).expect("Failed to parse SMTP_FROM"), + }; + + if mailer.is_some() && mail_from.is_none() { + panic!("SMTP_URL was provided, but SMTP_FROM was not"); + } + let routes = Arc::new(routes::route_root()); let base_context = Arc::new(BaseContext { local_hostname: get_url_host(&host_url_apub) .expect("Couldn't find host in HOST_URL_ACTIVITYPUB"), db_pool, + mailer, + mail_from, host_url_api, host_url_apub, http_client: hyper::Client::builder().build(hyper_tls::HttpsConnector::new()), |