Add Filesystem mail store and MultiDomain trait

This commit is contained in:
Nathan Fisher 2023-05-28 19:22:58 -04:00
parent 2afbede154
commit 72c1dbf016
2 changed files with 108 additions and 0 deletions

100
src/mailstore/filesystem.rs Normal file
View file

@ -0,0 +1,100 @@
use super::*;
use std::{fs, io, os::unix::fs::DirBuilderExt, path::PathBuf};
pub trait MultiDomain: MailStore {
type Error;
fn domains(&self) -> Result<Vec<String>, Self::Error>;
fn add_domain(&mut self, domain: &str) -> Result<(), Self::Error>;
fn remove_domain(&mut self, domain: &str) -> Result<(), Self::Error>;
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Filesystem {
pub path: PathBuf,
}
impl MailStore for Filesystem {
fn users(&self) -> Vec<Mailuser> {
todo!()
}
fn serves_domain(&self, domain: &str) -> bool {
let mut path = self.path.clone();
path.push(domain);
path.exists()
}
fn has_mailuser(&self, mailuser: &str) -> bool {
if let Some((user, host)) = mailuser.rsplit_once('@') {
let mut path = self.path.clone();
if host.contains('.') && !host.contains(|c: char| c.is_whitespace()) {
path.push(host);
path.push(user);
return path.exists();
}
}
false
}
fn get_user_messages(&self, user: &str) -> Option<BTreeMap<String, Message>> {
todo!()
}
fn get_message(&self, user: &str, title: &str) -> Option<Message> {
todo!()
}
fn move_message(&mut self, user: &str, title: &str, folder: &str) {
todo!()
}
fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError> {
todo!()
}
fn remove_user(&mut self, user: &str) -> bool {
todo!()
}
}
impl MultiDomain for Filesystem {
type Error = io::Error;
fn domains(&self) -> Result<Vec<String>, Self::Error> {
Ok(self
.path
.read_dir()?
.filter(|x| {
if let Ok(x) = x {
if let Ok(t) = x.file_type() {
return t.is_dir();
}
}
false
})
.map(|x| x.unwrap().file_name().to_string_lossy().to_string())
.collect::<Vec<String>>())
}
fn add_domain(&mut self, domain: &str) -> Result<(), Self::Error> {
let mut path = self.path.clone();
path.push(domain);
if !path.exists() {
fs::DirBuilder::new()
.recursive(true)
.mode(700)
.create(path)?;
}
Ok(())
}
fn remove_domain(&mut self, domain: &str) -> Result<(), Self::Error> {
let mut path = self.path.clone();
path.push(domain);
if path.exists() {
fs::remove_dir_all(path)?;
}
Ok(())
}
}

View file

@ -7,6 +7,8 @@ use std::{
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub mod filesystem;
pub trait MailStore {
/// Retreives a list of all valid mailusers on this server
fn users(&self) -> Vec<Mailuser>;
@ -19,6 +21,8 @@ pub trait MailStore {
/// 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>;
/// Move a message to a new folder
fn move_message(&mut self, user: &str, title: &str, folder: &str);
/// 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
@ -80,6 +84,10 @@ impl MailStore for Domain {
.cloned()
}
fn move_message(&mut self, user: &str, title: &str, folder: &str) {
todo!()
}
fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError> {
if self.users.contains_key(user) {
return Ok(());