From 8b7eb1ca918d26901b0739526341128067ca1cbc Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 29 Jun 2022 13:41:05 +0200 Subject: [PATCH] work on prototypes --- src/imap/command/anonymous.rs | 4 ++-- src/imap/command/authenticated.rs | 2 +- src/imap/command/selected.rs | 2 +- src/imap/flow.rs | 1 - src/lmtp.rs | 4 ++-- src/mail/mailbox.rs | 37 +++++++++++++++++-------------- src/mail/mod.rs | 2 +- src/mail/user.rs | 25 +++++++++++++++++++-- 8 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/imap/command/anonymous.rs b/src/imap/command/anonymous.rs index 5f982ba..8cd986c 100644 --- a/src/imap/command/anonymous.rs +++ b/src/imap/command/anonymous.rs @@ -1,12 +1,12 @@ use anyhow::{Error, Result}; use boitalettres::proto::{res::body::Data as Body, Request, Response}; use imap_codec::types::command::CommandBody; -use imap_codec::types::core::{AString}; +use imap_codec::types::core::AString; use imap_codec::types::response::{Capability, Data, Status}; use crate::imap::flow; -use crate::mail::user::User; use crate::login::ArcLoginProvider; +use crate::mail::user::User; //--- dispatching diff --git a/src/imap/command/authenticated.rs b/src/imap/command/authenticated.rs index b79865f..47df5be 100644 --- a/src/imap/command/authenticated.rs +++ b/src/imap/command/authenticated.rs @@ -96,7 +96,7 @@ impl<'a> AuthenticatedContext<'a> { async fn select(self, mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> { let name = String::try_from(mailbox.clone())?; - let mut mb = self.user.open_mailbox(name.clone())?; + let mut mb = self.user.open_mailbox(name)?; tracing::info!(username=%self.user.username, mailbox=%name, "mailbox.selected"); let sum = mb.summary().await?; diff --git a/src/imap/command/selected.rs b/src/imap/command/selected.rs index bd46bd5..b1bba23 100644 --- a/src/imap/command/selected.rs +++ b/src/imap/command/selected.rs @@ -1,4 +1,4 @@ -use anyhow::{Result}; +use anyhow::Result; use boitalettres::proto::Request; use boitalettres::proto::Response; use imap_codec::types::command::CommandBody; diff --git a/src/imap/flow.rs b/src/imap/flow.rs index 369bee6..0fe6f92 100644 --- a/src/imap/flow.rs +++ b/src/imap/flow.rs @@ -4,7 +4,6 @@ use std::fmt; use crate::mail::mailbox::Mailbox; use crate::mail::user::User; - #[derive(Debug)] pub enum Error { ForbiddenTransition, diff --git a/src/lmtp.rs b/src/lmtp.rs index 9036874..d74a315 100644 --- a/src/lmtp.rs +++ b/src/lmtp.rs @@ -2,14 +2,14 @@ use std::collections::HashMap; use std::net::SocketAddr; use std::{pin::Pin, sync::Arc}; -use anyhow::{Result}; +use anyhow::Result; use async_trait::async_trait; use duplexify::Duplex; use futures::{io, AsyncRead, AsyncReadExt, AsyncWrite}; use futures::{stream, stream::FuturesUnordered, StreamExt}; use log::*; use rusoto_s3::{PutObjectRequest, S3}; -use tokio::net::{TcpListener}; +use tokio::net::TcpListener; use tokio::select; use tokio::sync::watch; use tokio_util::compat::*; diff --git a/src/mail/mailbox.rs b/src/mail/mailbox.rs index e19dfd8..a2d28fb 100644 --- a/src/mail/mailbox.rs +++ b/src/mail/mailbox.rs @@ -19,6 +19,7 @@ pub struct Summary<'a> { pub flags: FlagIter<'a>, pub unseen: Option<&'a ImapUid>, } + impl std::fmt::Display for Summary<'_> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( @@ -44,14 +45,14 @@ pub struct Mailbox { } impl Mailbox { - pub(super) fn new(creds: &Credentials, name: String) -> Result { + pub(super) fn new(creds: &Credentials, name: &str) -> Result { let index_path = format!("index/{}", name); let mail_path = format!("mail/{}", name); let uid_index = Bayou::::new(creds, index_path)?; Ok(Self { bucket: creds.bucket().to_string(), - name, + name: name.to_string(), // TODO: don't use name field if possible, use mail_path instead key: creds.keys.master.clone(), k2v: creds.k2v_client()?, s3: creds.s3_client()?, @@ -60,7 +61,7 @@ impl Mailbox { }) } - // Get a summary of the mailbox, useful for the SELECT command for example + /// Get a summary of the mailbox, useful for the SELECT command for example pub async fn summary(&mut self) -> Result { self.uid_index.sync().await?; let state = self.uid_index.state(); @@ -85,34 +86,36 @@ impl Mailbox { }); } - // Insert an email in the mailbox + /// Insert an email in the mailbox pub async fn append(&mut self, _msg: IMF) -> Result<()> { - Ok(()) + unimplemented!() } - // Copy an email from an external to this mailbox - // @FIXME is it needed or could we implement it with append? - pub async fn copy(&mut self, _mailbox: String, _uid: ImapUid) -> Result<()> { - Ok(()) + /// Copy an email from an other Mailbox to this mailbox + /// (use this when possible, as it allows for a certain number of storage optimizations) + pub async fn copy(&mut self, _from: &Mailbox, _uid: ImapUid) -> Result<()> { + unimplemented!() } - // Delete all emails with the \Delete flag in the mailbox - // Can be called by CLOSE and EXPUNGE - // @FIXME do we want to implement this feature or a simpler "delete" command - // The controller could then "fetch \Delete" and call delete on each email? + /// Delete all emails with the \Delete flag in the mailbox + /// Can be called by CLOSE and EXPUNGE + /// @FIXME do we want to implement this feature or a simpler "delete" command + /// The controller could then "fetch \Delete" and call delete on each email? pub async fn expunge(&mut self) -> Result<()> { - Ok(()) + unimplemented!() } - // Update flags of a range of emails + /// Update flags of a range of emails pub async fn store(&mut self) -> Result<()> { - Ok(()) + unimplemented!() } pub async fn fetch(&mut self) -> Result<()> { - Ok(()) + unimplemented!() } + // ---- + pub async fn test(&mut self) -> Result<()> { self.uid_index.sync().await?; diff --git a/src/mail/mod.rs b/src/mail/mod.rs index f696f6d..4339038 100644 --- a/src/mail/mod.rs +++ b/src/mail/mod.rs @@ -1,7 +1,7 @@ pub mod mail_ident; -pub mod user; pub mod mailbox; mod uidindex; +pub mod user; use std::convert::TryFrom; diff --git a/src/mail/user.rs b/src/mail/user.rs index 7465ab0..4864509 100644 --- a/src/mail/user.rs +++ b/src/mail/user.rs @@ -25,7 +25,28 @@ impl User { }) } - pub fn open_mailbox(&self, name: String) -> Result { - Mailbox::new(&self.creds, name) + /// Lists user's available mailboxes + pub fn list_mailboxes(&self) -> Result> { + unimplemented!() + } + + /// Opens an existing mailbox given its IMAP name. + pub fn open_mailbox(&self, name: &str) -> Result> { + Mailbox::new(&self.creds, name).map(Some) + } + + /// Creates a new mailbox in the user's IMAP namespace. + pub fn create_mailbox(&self, name: &str) -> Result<()> { + unimplemented!() + } + + /// Deletes a mailbox in the user's IMAP namespace. + pub fn delete_mailbox(&self, name: &str) -> Result<()> { + unimplemented!() + } + + /// Renames a mailbox in the user's IMAP namespace. + pub fn rename_mailbox(&self, old_name: &str, new_name: &str) -> Result<()> { + unimplemented!() } }