server: use async api for email sending

Fixes #378
This commit is contained in:
Michał Mrozek 2022-11-24 14:47:56 +01:00 committed by GitHub
parent 80fc94c4db
commit dd7e392626
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 12 deletions

View File

@ -179,7 +179,9 @@ where
&token, &token,
&data.server_url, &data.server_url,
&data.mail_options, &data.mail_options,
) { )
.await
{
warn!("Error sending email: {:#?}", e); warn!("Error sending email: {:#?}", e);
return Err(TcpError::InternalServerError(format!( return Err(TcpError::InternalServerError(format!(
"Could not send email: {}", "Could not send email: {}",

View File

@ -1,12 +1,12 @@
use crate::infra::{cli::SmtpEncryption, configuration::MailOptions}; use crate::infra::{cli::SmtpEncryption, configuration::MailOptions};
use anyhow::Result; use anyhow::{Ok, Result};
use lettre::{ use lettre::{
message::Mailbox, transport::smtp::authentication::Credentials, Message, SmtpTransport, message::Mailbox, transport::smtp::authentication::Credentials, AsyncSmtpTransport,
Transport, AsyncTransport, Message, Tokio1Executor,
}; };
use tracing::debug; use tracing::debug;
fn send_email(to: Mailbox, subject: &str, body: String, options: &MailOptions) -> Result<()> { async fn send_email(to: Mailbox, subject: &str, body: String, options: &MailOptions) -> Result<()> {
let from = options let from = options
.from .from
.clone() .clone()
@ -27,15 +27,15 @@ fn send_email(to: Mailbox, subject: &str, body: String, options: &MailOptions) -
options.password.unsecure().to_string(), options.password.unsecure().to_string(),
); );
let relay_factory = match options.smtp_encryption { let relay_factory = match options.smtp_encryption {
SmtpEncryption::TLS => SmtpTransport::relay, SmtpEncryption::TLS => AsyncSmtpTransport::<Tokio1Executor>::relay,
SmtpEncryption::STARTTLS => SmtpTransport::starttls_relay, SmtpEncryption::STARTTLS => AsyncSmtpTransport::<Tokio1Executor>::starttls_relay,
}; };
let mailer = relay_factory(&options.server)?.credentials(creds).build(); let mailer = relay_factory(&options.server)?.credentials(creds).build();
mailer.send(&email)?; mailer.send(email).await?;
Ok(()) Ok(())
} }
pub fn send_password_reset_email( pub async fn send_password_reset_email(
username: &str, username: &str,
to: &str, to: &str,
token: &str, token: &str,
@ -54,14 +54,15 @@ To reset your password please visit the following URL: {}/reset-password/step2/{
Please contact an administrator if you did not initiate the process.", Please contact an administrator if you did not initiate the process.",
username, domain, token username, domain, token
); );
send_email(to, "[LLDAP] Password reset requested", body, options) send_email(to, "[LLDAP] Password reset requested", body, options).await
} }
pub fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> { pub async fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
send_email( send_email(
to, to,
"LLDAP test email", "LLDAP test email",
"The test is successful! You can send emails from LLDAP".to_string(), "The test is successful! You can send emails from LLDAP".to_string(),
options, options,
) )
.await
} }

View File

@ -131,7 +131,16 @@ fn send_test_email_command(opts: TestEmailOpts) -> Result<()> {
let to = opts.to.parse()?; let to = opts.to.parse()?;
let config = infra::configuration::init(opts)?; let config = infra::configuration::init(opts)?;
infra::logging::init(&config)?; infra::logging::init(&config)?;
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;
runtime.block_on(
mail::send_test_email(to, &config.smtp_options) mail::send_test_email(to, &config.smtp_options)
.unwrap_or_else(|e| error!("Could not send email: {:#}", e)),
);
Ok(())
} }
fn run_healthcheck(opts: RunOpts) -> Result<()> { fn run_healthcheck(opts: RunOpts) -> Result<()> {