Add Account
, Domain
, MultiDomain
structs and MailStore
trait
This commit is contained in:
parent
c7ed63a260
commit
2afbede154
5 changed files with 131 additions and 11 deletions
|
@ -52,3 +52,19 @@ impl GetFingerprint for Certificate {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const CERT: &[u8] = include_bytes!("../../test/certificates/gemini.example.org/cert.der");
|
||||||
|
const FP: &'static str =
|
||||||
|
include_str!("../../test/certificates/gemini.example.org/fingerprint.txt");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_fingerprint() {
|
||||||
|
let cert = Certificate(CERT.into());
|
||||||
|
let fp = cert.fingerprint().unwrap();
|
||||||
|
assert_eq!(fp.fingerprint, FP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
src/lib.rs
25
src/lib.rs
|
@ -1,13 +1,16 @@
|
||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
mod certificate;
|
pub mod certificate;
|
||||||
mod fingerprint;
|
pub mod fingerprint;
|
||||||
mod host;
|
pub mod host;
|
||||||
mod mailbox;
|
pub mod mailbox;
|
||||||
mod mailuser;
|
pub mod mailstore;
|
||||||
mod message;
|
pub mod mailuser;
|
||||||
|
pub mod message;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
mod receiver;
|
pub mod receiver;
|
||||||
mod request;
|
pub mod request;
|
||||||
mod response;
|
pub mod response;
|
||||||
mod sender;
|
pub mod sender;
|
||||||
mod status;
|
pub mod status;
|
||||||
|
|
||||||
|
pub use sender::{Error as SenderError, Sender};
|
||||||
|
|
100
src/mailstore/mod.rs
Normal file
100
src/mailstore/mod.rs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
use crate::prelude::{Host, Mailbox, Mailuser, Message, ParseMailboxError};
|
||||||
|
use std::{
|
||||||
|
collections::{BTreeMap, HashMap},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub trait MailStore {
|
||||||
|
/// Retreives a list of all valid mailusers on this server
|
||||||
|
fn users(&self) -> Vec<Mailuser>;
|
||||||
|
/// Checks whether this server services that domain
|
||||||
|
fn serves_domain(&self, domain: &str) -> bool;
|
||||||
|
/// Checks whether this server has the given mailuser
|
||||||
|
fn has_mailuser(&self, mailuser: &str) -> bool;
|
||||||
|
/// Retreives all of the messages for this user
|
||||||
|
fn get_user_messages(&self, user: &str) -> Option<BTreeMap<String, Message>>;
|
||||||
|
/// Checks whether this server has a message with the given title for this user and if so
|
||||||
|
/// returns the message
|
||||||
|
fn get_message(&self, user: &str, title: &str) -> Option<Message>;
|
||||||
|
/// Adds a new mailuser to the given domain
|
||||||
|
fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError>;
|
||||||
|
/// Removes the given user if the account exists
|
||||||
|
fn remove_user(&mut self, user: &str) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct Domain {
|
||||||
|
pub host: Host,
|
||||||
|
pub users: HashMap<String, Account>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct Account {
|
||||||
|
pub user: Mailbox,
|
||||||
|
pub messages: BTreeMap<String, Message>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct MultiDomain {
|
||||||
|
pub domains: HashMap<String, Domain>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MailStore for Domain {
|
||||||
|
fn users(&self) -> Vec<Mailuser> {
|
||||||
|
self.users
|
||||||
|
.values()
|
||||||
|
.map(|act| act.user.clone().into())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serves_domain(&self, domain: &str) -> bool {
|
||||||
|
self.host.to_string().as_str() == domain
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_mailuser(&self, mailuser: &str) -> bool {
|
||||||
|
self.users()
|
||||||
|
.iter()
|
||||||
|
.find(|x| x.username == mailuser)
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_user_messages(&self, user: &str) -> Option<BTreeMap<String, Message>> {
|
||||||
|
self.users.get(user).cloned().map(|u| u.messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_message(&self, user: &str, title: &str) -> Option<Message> {
|
||||||
|
self.users
|
||||||
|
.get(user)
|
||||||
|
.map(|u| {
|
||||||
|
u.messages
|
||||||
|
.values()
|
||||||
|
.find(|m| m.title.as_ref().map(|x| x.as_str()) == Some(title))
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError> {
|
||||||
|
if self.users.contains_key(user) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let mbox = Mailbox::from_str(&format!("{user}@{}", self.host.to_string()))?;
|
||||||
|
let messages = BTreeMap::new();
|
||||||
|
let acct = Account {
|
||||||
|
user: mbox,
|
||||||
|
messages,
|
||||||
|
};
|
||||||
|
self.users.insert(user.to_string(), acct);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_user(&mut self, user: &str) -> bool {
|
||||||
|
self.users.remove(user).is_some()
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,6 +59,7 @@ pub struct Message {
|
||||||
pub senders: Vec<Mailbox>,
|
pub senders: Vec<Mailbox>,
|
||||||
pub recipients: Vec<Mailbox>,
|
pub recipients: Vec<Mailbox>,
|
||||||
pub timstamp: Option<String>,
|
pub timstamp: Option<String>,
|
||||||
|
pub title: Option<String>,
|
||||||
pub body: String,
|
pub body: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
0
src/message/parser.rs
Normal file
0
src/message/parser.rs
Normal file
Loading…
Add table
Reference in a new issue