Merge pull request #422 from amousset/sender
fix(builder): Fail if required headers are missing (fixes #95)
This commit is contained in:
18
src/lib.rs
18
src/lib.rs
@@ -25,12 +25,11 @@ pub mod error;
|
||||
pub mod message;
|
||||
pub mod transport;
|
||||
|
||||
pub use crate::address::Address;
|
||||
use crate::error::Error;
|
||||
#[cfg(feature = "builder")]
|
||||
pub use crate::message::{
|
||||
header::{self, Headers},
|
||||
EmailFormat, Mailboxes, Message,
|
||||
EmailFormat, Mailbox, Mailboxes, Message,
|
||||
};
|
||||
#[cfg(feature = "file-transport")]
|
||||
pub use crate::transport::file::FileTransport;
|
||||
@@ -42,11 +41,10 @@ pub use crate::transport::smtp::client::net::TlsParameters;
|
||||
pub use crate::transport::smtp::r2d2::SmtpConnectionManager;
|
||||
#[cfg(feature = "smtp-transport")]
|
||||
pub use crate::transport::smtp::{SmtpTransport, Tls};
|
||||
pub use crate::transport::stub::StubTransport;
|
||||
pub use crate::{address::Address, transport::stub::StubTransport};
|
||||
#[cfg(feature = "builder")]
|
||||
use std::convert::TryFrom;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::{error::Error as StdError, fmt};
|
||||
|
||||
/// Simple email envelope representation
|
||||
///
|
||||
@@ -92,9 +90,15 @@ impl TryFrom<&Headers> for Envelope {
|
||||
let from = match headers.get::<header::Sender>() {
|
||||
// If there is a Sender, use it
|
||||
Some(header::Sender(a)) => Some(a.email.clone()),
|
||||
// ... else use the first From address
|
||||
// ... else try From
|
||||
None => match headers.get::<header::From>() {
|
||||
Some(header::From(ref a)) => Some(a.iter().next().unwrap().email.clone()),
|
||||
Some(header::From(a)) => {
|
||||
let from: Vec<Mailbox> = a.clone().into();
|
||||
if from.len() > 1 {
|
||||
return Err(Error::TooManyFrom);
|
||||
}
|
||||
Some(from[0].email.clone())
|
||||
}
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -364,25 +364,32 @@ impl MessageBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
fn insert_missing_headers(self) -> Self {
|
||||
let mut new = self;
|
||||
|
||||
// Insert Date if missing
|
||||
new = if new.headers.get::<header::Date>().is_none() {
|
||||
new.date_now()
|
||||
} else {
|
||||
new
|
||||
};
|
||||
|
||||
// TODO insert sender if needed?
|
||||
new
|
||||
}
|
||||
|
||||
// TODO: High-level methods for attachments and embedded files
|
||||
|
||||
/// Create message from body
|
||||
fn build(self, body: Body) -> Result<Message, EmailError> {
|
||||
let res = self.insert_missing_headers();
|
||||
// Check for missing required headers
|
||||
// https://tools.ietf.org/html/rfc5322#section-3.6
|
||||
|
||||
// Insert Date if missing
|
||||
let res = if self.headers.get::<header::Date>().is_none() {
|
||||
self.date_now()
|
||||
} else {
|
||||
self
|
||||
};
|
||||
|
||||
// Fail is missing correct originator (Sender or From)
|
||||
match res.headers.get::<header::From>() {
|
||||
Some(header::From(f)) => {
|
||||
let from: Vec<Mailbox> = f.clone().into();
|
||||
if from.len() > 1 && res.headers.get::<header::Sender>().is_none() {
|
||||
return Err(EmailError::TooManyFrom);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return Err(EmailError::MissingFrom);
|
||||
}
|
||||
}
|
||||
|
||||
let envelope = match res.envelope {
|
||||
Some(e) => e,
|
||||
@@ -485,6 +492,29 @@ impl Default for MessageBuilder {
|
||||
mod test {
|
||||
use crate::message::{header, mailbox::Mailbox, Message};
|
||||
|
||||
#[test]
|
||||
fn email_missing_originator() {
|
||||
assert!(Message::builder().body("Happy new year!").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn email_miminal_message() {
|
||||
assert!(Message::builder()
|
||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
.to("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
.body("Happy new year!")
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn email_missing_sender() {
|
||||
assert!(Message::builder()
|
||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
.from("AnyBody <anybody@domain.tld>".parse().unwrap())
|
||||
.body("Happy new year!")
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn email_message() {
|
||||
let date = "Tue, 15 Nov 1994 08:12:31 GMT".parse().unwrap();
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
//! ```
|
||||
|
||||
use crate::{Envelope, Transport};
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::{error::Error as StdError, fmt};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Error;
|
||||
|
||||
Reference in New Issue
Block a user