Integrate unique message id creation with message receipt; Add

appropriate error cases for new infra;
This commit is contained in:
Nathan Fisher 2023-06-26 18:56:14 -04:00
parent 49b6728c78
commit 8dcd8455d4
5 changed files with 80 additions and 22 deletions

View file

@ -1,26 +1,28 @@
use { use {
crate::prelude::ParseRequestError, crate::prelude::{IdError, ParseMessageError, ParseRequestError},
std::{fmt, io, string::FromUtf8Error, time::SystemTimeError}, std::{fmt, io, string::FromUtf8Error},
}; };
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
Message(ParseMessageError),
Id(IdError),
Io(io::Error), Io(io::Error),
Request(ParseRequestError), Request(ParseRequestError),
Storage(String), Storage(String),
Rustls(rustls::Error), Rustls(rustls::Error),
Time(SystemTimeError),
Utf8, Utf8,
} }
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Message(e) => write!(f, "{e}"),
Self::Id(e) => write!(f, "{e}"),
Self::Io(e) => write!(f, "{e}"), Self::Io(e) => write!(f, "{e}"),
Self::Storage(e) => write!(f, "{e}"), Self::Storage(e) => write!(f, "{e}"),
Self::Request(e) => write!(f, "{e}"), Self::Request(e) => write!(f, "{e}"),
Self::Rustls(e) => write!(f, "{e}"), Self::Rustls(e) => write!(f, "{e}"),
Self::Time(e) => write!(f, "{e}"),
Self::Utf8 => write!(f, "Utf8 error"), Self::Utf8 => write!(f, "Utf8 error"),
} }
} }
@ -29,21 +31,34 @@ impl fmt::Display for Error {
impl std::error::Error for Error { impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self { match self {
Self::Message(e) => Some(e),
Self::Id(e) => Some(e),
Self::Io(e) => Some(e), Self::Io(e) => Some(e),
Self::Request(e) => Some(e), Self::Request(e) => Some(e),
Self::Rustls(e) => Some(e), Self::Rustls(e) => Some(e),
Self::Time(e) => Some(e),
_ => None, _ => None,
} }
} }
} }
impl From<IdError> for Error {
fn from(value: IdError) -> Self {
Self::Id(value)
}
}
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(value: io::Error) -> Self { fn from(value: io::Error) -> Self {
Self::Io(value) Self::Io(value)
} }
} }
impl From<ParseMessageError> for Error {
fn from(value: ParseMessageError) -> Self {
Self::Message(value)
}
}
impl From<ParseRequestError> for Error { impl From<ParseRequestError> for Error {
fn from(value: ParseRequestError) -> Self { fn from(value: ParseRequestError) -> Self {
Self::Request(value) Self::Request(value)
@ -56,12 +71,6 @@ impl From<rustls::Error> for Error {
} }
} }
impl From<SystemTimeError> for Error {
fn from(value: SystemTimeError) -> Self {
Self::Time(value)
}
}
impl From<FromUtf8Error> for Error { impl From<FromUtf8Error> for Error {
fn from(_value: FromUtf8Error) -> Self { fn from(_value: FromUtf8Error) -> Self {
Self::Utf8 Self::Utf8

View file

@ -5,14 +5,13 @@ pub mod verifier;
use { use {
crate::{ crate::{
prelude::{ClientCertificateStore, MailStore}, prelude::{ClientCertificateStore, Id, MailStore, MessageParser},
request::Request, request::Request,
response::Response, response::Response,
}, },
std::{ std::{
io::Read, io::Read,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::{SystemTime, UNIX_EPOCH},
}, },
}; };
@ -37,11 +36,12 @@ impl Connection {
self.inner.reader().read_to_end(&mut buf)?; self.inner.reader().read_to_end(&mut buf)?;
let raw = String::from_utf8(buf)?; let raw = String::from_utf8(buf)?;
let request: Request = raw.parse()?; let request: Request = raw.parse()?;
let res = if let Ok(store) = mailstore.lock() { let res = if let Ok(mut store) = mailstore.lock() {
if store.has_mailuser(&request.recipient.to_string()) { if store.has_mailuser(&request.recipient.to_string()) {
let time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(); let id = Id::new()?;
//store.add_message(&request.recipient.to_string(), "Inbox", request.message) let msg = MessageParser::new(&id.to_string()).parse(&request.message)?;
// .map_err(|e| Error::Storage(e.to_string()))?; store.add_message(&request.recipient.to_string(), "Inbox", msg)
.map_err(|e| Error::Storage(e.to_string()))?;
true true
} else { } else {
false false

View file

@ -1,10 +1,10 @@
use { use {
std::{ std::{
error::Error, error,
fmt, fmt,
fs::File, fs::File,
io::{self, Read}, io::{self, Read},
time::{SystemTime, UNIX_EPOCH}, time::{SystemTime, SystemTimeError, UNIX_EPOCH},
}, },
tinyrand::{RandRange, Seeded, StdRand}, tinyrand::{RandRange, Seeded, StdRand},
}; };
@ -30,7 +30,7 @@ impl fmt::Display for Id {
} }
impl Id { impl Id {
pub fn new() -> Result<Self, Box<dyn Error>> { pub fn new() -> Result<Self, Error> {
let time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(); let time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
let mut rand = StdRand::seed(random_seed()?); let mut rand = StdRand::seed(random_seed()?);
let mut id = ['0', '0', '0', '0', '0', '0', '0', '0']; let mut id = ['0', '0', '0', '0', '0', '0', '0', '0'];
@ -43,6 +43,42 @@ impl Id {
} }
} }
#[derive(Debug)]
pub enum Error {
Io(io::Error),
Time(SystemTimeError),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(e) => write!(f, "{e}"),
Self::Time(e) => write!(f, "{e}"),
}
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
Self::Io(e) => Some(e),
Self::Time(e) => Some(e),
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
impl From<SystemTimeError> for Error {
fn from(value: SystemTimeError) -> Self {
Self::Time(value)
}
}
fn u64_from_bytes(b: [u8; 8]) -> u64 { fn u64_from_bytes(b: [u8; 8]) -> u64 {
u64::from(b[0]) u64::from(b[0])
| (u64::from(b[1]) << 8) | (u64::from(b[1]) << 8)
@ -60,3 +96,16 @@ fn random_seed() -> io::Result<u64> {
fd.read_exact(&mut buf)?; fd.read_exact(&mut buf)?;
Ok(u64_from_bytes(buf)) Ok(u64_from_bytes(buf))
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn new_id() {
let a = Id::new().unwrap();
let b = Id::new().unwrap();
assert_eq!(a.time / 10, b.time / 10);
assert_ne!(a.id, b.id);
}
}

View file

@ -9,7 +9,7 @@ mod error;
mod id; mod id;
mod link; mod link;
mod parser; mod parser;
pub use {error::Error, id::Id, link::Link, parser::Parser}; pub use {error::Error, id::{Error as IdError, Id}, link::Link, parser::Parser};
#[derive(Clone, Debug, Default, PartialEq)] #[derive(Clone, Debug, Default, PartialEq)]
pub struct Recipients { pub struct Recipients {

View file

@ -6,7 +6,7 @@ pub use super::{
mailbox::{Error as ParseMailboxError, Mailbox}, mailbox::{Error as ParseMailboxError, Mailbox},
mailstore::{Account, Domain, Filesystem, FilesystemError, Folder, MailStore}, mailstore::{Account, Domain, Filesystem, FilesystemError, Folder, MailStore},
mailuser::Mailuser, mailuser::Mailuser,
message::{Error as ParseMessageError, Id, Link, Message, Recipients}, message::{Error as ParseMessageError, Id, IdError, Link, Message, Parser as MessageParser, Recipients},
//receiver, //receiver,
request::{Error as ParseRequestError, Request}, request::{Error as ParseRequestError, Request},
response::{Error as ParseResponseError, Response}, response::{Error as ParseResponseError, Response},