1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

mas-email: better errors & aws-sdk upgrade

This commit is contained in:
Quentin Gliech
2022-12-15 13:03:51 +01:00
parent fbbb842255
commit 306b71baf5
6 changed files with 118 additions and 71 deletions

View File

@ -6,15 +6,14 @@ edition = "2021"
license = "Apache-2.0"
[dependencies]
anyhow = "1.0.66"
async-trait = "0.1.59"
tokio = { version = "1.23.0", features = ["macros"] }
tracing = "0.1.37"
thiserror = "1.0.37"
aws-sdk-sesv2 = { version = "0.21.0", default-features = false }
aws-config = { version = "0.51.0", default-features = false }
aws-smithy-client = { version = "0.51.0", default-features = false, features = ["client-hyper"] }
aws-smithy-async = { version = "0.51.0", default-features = false, features = ["rt-tokio"] }
aws-sdk-sesv2 = { version = "0.22.0", default-features = false }
aws-config = { version = "0.52.0", default-features = false }
aws-smithy-client = { version = "0.52.0", default-features = false, features = ["client-hyper"] }
aws-smithy-async = { version = "0.52.0", default-features = false, features = ["rt-tokio"] }
mas-templates = { path = "../templates" }
mas-http = { path = "../http", features = ["aws-sdk", "client"] }

View File

@ -19,6 +19,7 @@ use lettre::{
AsyncTransport, Message,
};
use mas_templates::{EmailVerificationContext, Templates};
use thiserror::Error;
use crate::MailTransport;
@ -31,6 +32,14 @@ pub struct Mailer {
reply_to: Mailbox,
}
#[derive(Debug, Error)]
#[error(transparent)]
pub enum Error {
Transport(#[from] crate::transport::Error),
Templates(#[from] mas_templates::TemplateError),
Content(#[from] lettre::error::Error),
}
impl Mailer {
/// Constructs a new [`Mailer`]
#[must_use]
@ -58,7 +67,7 @@ impl Mailer {
&self,
to: Mailbox,
context: &EmailVerificationContext,
) -> anyhow::Result<Message> {
) -> Result<Message, Error> {
let plain = self
.templates
.render_email_verification_txt(context)
@ -105,7 +114,7 @@ impl Mailer {
&self,
to: Mailbox,
context: &EmailVerificationContext,
) -> anyhow::Result<()> {
) -> Result<(), Error> {
let message = self.prepare_verification_email(to, context).await?;
self.transport.send(message).await?;
Ok(())
@ -116,7 +125,7 @@ impl Mailer {
/// # Errors
///
/// Returns an error if the connection failed
pub async fn test_connection(&self) -> Result<(), anyhow::Error> {
pub async fn test_connection(&self) -> Result<(), crate::transport::Error> {
self.transport.test_connection().await
}
}

View File

@ -19,6 +19,7 @@ use aws_config::provider_config::ProviderConfig;
use aws_sdk_sesv2::{
middleware::DefaultMiddleware,
model::{EmailContent, RawMessage},
output::SendEmailOutput,
types::Blob,
Client,
};
@ -27,6 +28,8 @@ use aws_smithy_client::erase::{DynConnector, DynMiddleware};
use lettre::{address::Envelope, AsyncTransport};
use mas_http::{otel::TraceLayer, ClientInitError};
pub type Error = aws_smithy_client::SdkError<aws_sdk_sesv2::error::SendEmailError>;
/// An asynchronous email transport that sends email via the AWS Simple Email
/// Service v2 API
pub struct Transport {
@ -76,17 +79,17 @@ impl Transport {
#[async_trait]
impl AsyncTransport for Transport {
type Ok = ();
type Error = anyhow::Error;
type Ok = SendEmailOutput;
type Error = Error;
async fn send_raw(&self, _envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error> {
let email = Blob::new(email);
let email = RawMessage::builder().data(email).build();
let email = EmailContent::builder().raw(email).build();
let req = self.client.send_email().content(email);
req.send().await?;
let request = self.client.send_email().content(email);
let response = request.send().await?;
Ok(())
Ok(response)
}
}

View File

@ -26,6 +26,7 @@ use lettre::{
AsyncTransport, Tokio1Executor,
};
use mas_http::ClientInitError;
use thiserror::Error;
pub mod aws_ses;
@ -119,7 +120,7 @@ impl Transport {
/// # Errors
///
/// Will return `Err` if the connection test failed
pub async fn test_connection(&self) -> anyhow::Result<()> {
pub async fn test_connection(&self) -> Result<(), Error> {
match self.inner.as_ref() {
TransportInner::Smtp(t) => {
t.test_connection().await?;
@ -138,10 +139,18 @@ impl Default for TransportInner {
}
}
#[derive(Debug, Error)]
#[error(transparent)]
pub enum Error {
Smtp(#[from] lettre::transport::smtp::Error),
Sendmail(#[from] lettre::transport::sendmail::Error),
AwsSes(#[from] self::aws_ses::Error),
}
#[async_trait]
impl AsyncTransport for Transport {
type Ok = ();
type Error = anyhow::Error;
type Error = Error;
async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error> {
match self.inner.as_ref() {