Fix some issues with Sender, add Multisender
This commit is contained in:
parent
b7378dba78
commit
e3b9db4572
3 changed files with 67 additions and 18 deletions
|
@ -12,14 +12,14 @@ pub use error::Error;
|
|||
/// The full request as sent by the `Sender` and received by the `Receiver`
|
||||
pub struct Request {
|
||||
/// The sender of the message
|
||||
pub sender: Mailuser,
|
||||
pub recipient: Mailuser,
|
||||
/// The message body
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Request {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "misfin://{} {}\r\n", self.sender, self.message)
|
||||
write!(f, "misfin://{} {}\r\n", self.recipient, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,8 @@ impl FromStr for Request {
|
|||
let Some(user) = user.strip_prefix("misfin://") else {
|
||||
return Err(Error::Malformed);
|
||||
};
|
||||
let sender = user.parse()?;
|
||||
Ok(Request { sender, message })
|
||||
let recipient = user.parse()?;
|
||||
Ok(Request { recipient, message })
|
||||
} else {
|
||||
Err(Error::MissingSeparator)
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ mod tests {
|
|||
|
||||
fn req() -> Request {
|
||||
Request {
|
||||
sender: Mailuser {
|
||||
recipient: Mailuser {
|
||||
username: "john".to_string(),
|
||||
host: Host {
|
||||
subdomain: Some("misfin".into()),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
crate::prelude::{ParseRequestError, ParseResponseError},
|
||||
crate::prelude::{ParseMailboxError, ParseRequestError, ParseResponseError},
|
||||
rustls::InvalidMessage,
|
||||
std::{fmt, io},
|
||||
};
|
||||
|
@ -9,10 +9,11 @@ use {
|
|||
pub enum Error {
|
||||
CertificateError(InvalidMessage),
|
||||
DnsError,
|
||||
TlsError(rustls::Error),
|
||||
IoError(io::Error),
|
||||
MailboxError(ParseMailboxError),
|
||||
RequestError(ParseRequestError),
|
||||
ResponseError(ParseResponseError),
|
||||
IoError(io::Error),
|
||||
TlsError(rustls::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
|
@ -20,10 +21,11 @@ impl fmt::Display for Error {
|
|||
match self {
|
||||
Self::CertificateError(e) => write!(f, "{e:?}"),
|
||||
Self::DnsError => write!(f, "Dns Error"),
|
||||
Self::TlsError(e) => write!(f, "{e}"),
|
||||
Self::IoError(e) => write!(f, "{e}"),
|
||||
Self::MailboxError(e) => write!(f, "{e}"),
|
||||
Self::RequestError(e) => write!(f, "{e}"),
|
||||
Self::ResponseError(e) => write!(f, "{e}"),
|
||||
Self::IoError(e) => write!(f, "{e}"),
|
||||
Self::TlsError(e) => write!(f, "{e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +33,11 @@ impl fmt::Display for Error {
|
|||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
Self::IoError(e) => Some(e),
|
||||
Self::MailboxError(e) => Some(e),
|
||||
Self::RequestError(e) => Some(e),
|
||||
Self::ResponseError(e) => Some(e),
|
||||
Self::TlsError(e) => Some(e),
|
||||
Self::IoError(e) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +55,12 @@ impl From<rustls::Error> for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ParseMailboxError> for Error {
|
||||
fn from(value: ParseMailboxError) -> Self {
|
||||
Self::MailboxError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseRequestError> for Error {
|
||||
fn from(value: ParseRequestError) -> Self {
|
||||
Self::RequestError(value)
|
||||
|
|
|
@ -21,6 +21,8 @@ where
|
|||
S: CertificateStore,
|
||||
C: ClientCertificateStore,
|
||||
{
|
||||
/// The address of the sender
|
||||
pub sender: Mailuser,
|
||||
/// The full message text to be sent
|
||||
pub request: Request,
|
||||
/// A [CertificateStore] for servers known to us
|
||||
|
@ -34,9 +36,11 @@ where
|
|||
S: CertificateStore + 'static,
|
||||
C: ClientCertificateStore,
|
||||
{
|
||||
pub fn new(request_str: &str, store: S, client_store: C) -> Result<Self, Error> {
|
||||
pub fn new(sender: &str, request_str: &str, store: S, client_store: C) -> Result<Self, Error> {
|
||||
let sender = sender.parse()?;
|
||||
let request: Request = request_str.parse()?;
|
||||
Ok(Self {
|
||||
sender,
|
||||
request,
|
||||
store,
|
||||
client_store,
|
||||
|
@ -44,17 +48,17 @@ where
|
|||
}
|
||||
|
||||
fn host_string(&self) -> String {
|
||||
self.request.sender.host.to_string()
|
||||
self.request.recipient.host.to_string()
|
||||
}
|
||||
|
||||
pub fn send(self, recipient: &Mailuser) -> Result<Response, Error> {
|
||||
let dnsname = recipient
|
||||
.to_string()
|
||||
pub fn send(self) -> Result<Response, Error> {
|
||||
let dnsname = self
|
||||
.host_string()
|
||||
.as_str()
|
||||
.try_into()
|
||||
.map_err(|_| Error::DnsError)?;
|
||||
let mut it = recipient.host.to_socket_addrs()?;
|
||||
let client_cert = self.client_store.get_certificate(&self.request.sender);
|
||||
let mut it = self.request.recipient.host.to_socket_addrs()?;
|
||||
let client_cert = self.client_store.get_certificate(&self.sender);
|
||||
let verifier = Arc::new(Verifier::new(self.store));
|
||||
let Some(socket_addrs) = it.next() else {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "no data retrieved").into());
|
||||
|
@ -83,3 +87,39 @@ where
|
|||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MultiSender<S, C>
|
||||
where
|
||||
S: CertificateStore,
|
||||
C: ClientCertificateStore,
|
||||
{
|
||||
pub sender: Mailuser,
|
||||
pub recipients: Vec<Mailuser>,
|
||||
pub store: S,
|
||||
pub client_store: C,
|
||||
}
|
||||
|
||||
impl<S, C> MultiSender<S, C>
|
||||
where
|
||||
S: CertificateStore + 'static + Clone,
|
||||
C: ClientCertificateStore + Clone,
|
||||
{
|
||||
pub fn new(sender: &str, recipients: &[&str], store: S, client_store: C) -> Result<Self, Error> {
|
||||
let mut rec = vec![];
|
||||
for r in recipients {
|
||||
let r = r.parse()?;
|
||||
rec.push(r);
|
||||
}
|
||||
Ok(Self {
|
||||
sender: sender.parse()?,
|
||||
recipients: rec,
|
||||
store,
|
||||
client_store
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send(&self, f: &dyn Fn(Result<Response, Error>)) -> Result<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue