114 lines
3.2 KiB
Rust
114 lines
3.2 KiB
Rust
use brass_config::{Config, SmtpTlsType};
|
|
use lettre::{
|
|
address::Envelope,
|
|
transport::{
|
|
smtp::{authentication::Credentials, extension::ClientId},
|
|
stub::AsyncStubTransport,
|
|
},
|
|
AsyncSmtpTransport, AsyncStd1Executor, AsyncTransport,
|
|
};
|
|
|
|
use crate::utils::ApplicationError;
|
|
|
|
mod forgot_password;
|
|
mod registration;
|
|
mod testmail;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Mailer {
|
|
transport: Transports,
|
|
hostname: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
enum Transports {
|
|
SmtpTransport(AsyncSmtpTransport<AsyncStd1Executor>),
|
|
#[allow(unused)]
|
|
StubTransport(AsyncStubTransport),
|
|
}
|
|
|
|
impl AsyncTransport for Transports {
|
|
type Ok = ();
|
|
type Error = ApplicationError;
|
|
|
|
fn send_raw<'life0, 'life1, 'life2, 'async_trait>(
|
|
&'life0 self,
|
|
envelope: &'life1 Envelope,
|
|
email: &'life2 [u8],
|
|
) -> ::core::pin::Pin<
|
|
Box<
|
|
dyn ::core::future::Future<Output = Result<Self::Ok, Self::Error>>
|
|
+ ::core::marker::Send
|
|
+ 'async_trait,
|
|
>,
|
|
>
|
|
where
|
|
'life0: 'async_trait,
|
|
'life1: 'async_trait,
|
|
'life2: 'async_trait,
|
|
Self: 'async_trait,
|
|
{
|
|
Box::pin(async move {
|
|
match self {
|
|
Transports::SmtpTransport(smtp_transport) => smtp_transport
|
|
.send_raw(envelope, email)
|
|
.await
|
|
.map(|_| ())
|
|
.map_err(ApplicationError::EmailTransport),
|
|
Transports::StubTransport(stub_transport) => stub_transport
|
|
.send_raw(envelope, email)
|
|
.await
|
|
.map(|_| ())
|
|
.map_err(ApplicationError::EmailStubTransport),
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Mailer {
|
|
pub fn new(config: &Config) -> anyhow::Result<Self> {
|
|
let mut builder = match config.smtp_tlstype {
|
|
SmtpTlsType::StartTLS => {
|
|
AsyncSmtpTransport::<AsyncStd1Executor>::starttls_relay(&config.smtp_server)?
|
|
.port(config.smtp_port)
|
|
}
|
|
SmtpTlsType::TLS => {
|
|
AsyncSmtpTransport::<AsyncStd1Executor>::relay(&config.smtp_server)?
|
|
.port(config.smtp_port)
|
|
}
|
|
SmtpTlsType::NoTLS => {
|
|
AsyncSmtpTransport::<AsyncStd1Executor>::builder_dangerous(&config.smtp_server)
|
|
.port(config.smtp_port)
|
|
}
|
|
};
|
|
|
|
if let (Some(login), Some(password)) =
|
|
(config.smtp_login.as_ref(), config.smtp_password.as_ref())
|
|
{
|
|
builder =
|
|
builder.credentials(Credentials::new(login.to_string(), password.to_string()));
|
|
}
|
|
|
|
let transport = builder
|
|
.hello_name(ClientId::Domain(config.hostname.clone()))
|
|
.build();
|
|
|
|
let mailer = Mailer {
|
|
transport: Transports::SmtpTransport(transport),
|
|
hostname: config.hostname.to_string(),
|
|
};
|
|
|
|
Ok(mailer)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
impl Mailer {
|
|
pub fn new_stub() -> Self {
|
|
Mailer {
|
|
transport: Transports::StubTransport(AsyncStubTransport::new_ok()),
|
|
hostname: String::from("testhostname"),
|
|
}
|
|
}
|
|
}
|