diff options
Diffstat (limited to 'src/imap/command/authenticated.rs')
-rw-r--r-- | src/imap/command/authenticated.rs | 113 |
1 files changed, 71 insertions, 42 deletions
diff --git a/src/imap/command/authenticated.rs b/src/imap/command/authenticated.rs index b4c4432..fca15fc 100644 --- a/src/imap/command/authenticated.rs +++ b/src/imap/command/authenticated.rs @@ -1,5 +1,4 @@ - -use anyhow::{Result, Error, anyhow}; +use anyhow::{anyhow, Error, Result}; use boitalettres::proto::Response; use imap_codec::types::command::CommandBody; use imap_codec::types::core::Tag; @@ -7,16 +6,29 @@ use imap_codec::types::mailbox::{ListMailbox, Mailbox as MailboxCodec}; use imap_codec::types::response::{Code, Data, Response as ImapRes, Status}; use crate::imap::command::anonymous; -use crate::imap::session::InnerContext; use crate::imap::flow; +use crate::imap::session::InnerContext; use crate::mailbox::Mailbox; -pub async fn dispatch<'a>(inner: InnerContext<'a>, user: &'a flow::User) -> Result<(Response, flow::Transition)> { - let ctx = StateContext { user, tag: &inner.req.tag, inner }; +pub async fn dispatch<'a>( + inner: InnerContext<'a>, + user: &'a flow::User, +) -> Result<(Response, flow::Transition)> { + let ctx = StateContext { + user, + tag: &inner.req.tag, + inner, + }; match &ctx.inner.req.body { - CommandBody::Lsub { reference, mailbox_wildcard, } => ctx.lsub(reference, mailbox_wildcard).await, - CommandBody::List { reference, mailbox_wildcard, } => ctx.list(reference, mailbox_wildcard).await, + CommandBody::Lsub { + reference, + mailbox_wildcard, + } => ctx.lsub(reference, mailbox_wildcard).await, + CommandBody::List { + reference, + mailbox_wildcard, + } => ctx.list(reference, mailbox_wildcard).await, CommandBody::Select { mailbox } => ctx.select(mailbox).await, _ => anonymous::dispatch(ctx.inner).await, } @@ -24,7 +36,6 @@ pub async fn dispatch<'a>(inner: InnerContext<'a>, user: &'a flow::User) -> Resu // --- PRIVATE --- - struct StateContext<'a> { inner: InnerContext<'a>, user: &'a flow::User, @@ -36,45 +47,50 @@ impl<'a> StateContext<'a> { &self, reference: &MailboxCodec, mailbox_wildcard: &ListMailbox, - ) -> Result<(Response, flow::Transition)> { - Ok((vec![ImapRes::Status( + ) -> Result<(Response, flow::Transition)> { + Ok(( + vec![ImapRes::Status( Status::bad(Some(self.tag.clone()), None, "Not implemented").map_err(Error::msg)?, - )], flow::Transition::No)) + )], + flow::Transition::No, + )) } async fn list( &self, reference: &MailboxCodec, mailbox_wildcard: &ListMailbox, - ) -> Result<(Response, flow::Transition)> { - Ok((vec![ - ImapRes::Status(Status::bad(Some(self.tag.clone()), None, "Not implemented").map_err(Error::msg)?), - ], flow::Transition::No)) + ) -> Result<(Response, flow::Transition)> { + Ok(( + vec![ImapRes::Status( + Status::bad(Some(self.tag.clone()), None, "Not implemented").map_err(Error::msg)?, + )], + flow::Transition::No, + )) } /* - * TRACE BEGIN --- + * TRACE BEGIN --- - Example: C: A142 SELECT INBOX - S: * 172 EXISTS - S: * 1 RECENT - S: * OK [UNSEEN 12] Message 12 is first unseen - S: * OK [UIDVALIDITY 3857529045] UIDs valid - S: * OK [UIDNEXT 4392] Predicted next UID - S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) - S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited - S: A142 OK [READ-WRITE] SELECT completed + Example: C: A142 SELECT INBOX + S: * 172 EXISTS + S: * 1 RECENT + S: * OK [UNSEEN 12] Message 12 is first unseen + S: * OK [UIDVALIDITY 3857529045] UIDs valid + S: * OK [UIDNEXT 4392] Predicted next UID + S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) + S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited + S: A142 OK [READ-WRITE] SELECT completed - * TRACE END --- - */ + * TRACE END --- + */ async fn select(&self, mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> { let name = String::try_from(mailbox.clone())?; let mut mb = Mailbox::new(&self.user.creds, name.clone())?; tracing::info!(username=%self.user.name, mailbox=%name, "mailbox.selected"); - let sum = mb.summary().await?; tracing::trace!(summary=%sum, "mailbox.summary"); @@ -82,21 +98,34 @@ impl<'a> StateContext<'a> { let tr = flow::Transition::Select(mb); - let r_unseen = Status::ok(None, Some(Code::Unseen(std::num::NonZeroU32::new(1).ok_or(anyhow!("Invalid message identifier"))?)), "First unseen UID").map_err(Error::msg)?; + let r_unseen = Status::ok( + None, + Some(Code::Unseen( + std::num::NonZeroU32::new(1).ok_or(anyhow!("Invalid message identifier"))?, + )), + "First unseen UID", + ) + .map_err(Error::msg)?; //let r_permanentflags = Status::ok(None, Some(Code:: - Ok((vec![ - ImapRes::Data(Data::Exists(0)), - ImapRes::Data(Data::Recent(0)), - ImapRes::Data(Data::Flags(vec![])), - /*ImapRes::Status(), - ImapRes::Status(), - ImapRes::Status(),*/ - ImapRes::Status(Status::ok( - Some(self.tag.clone()), - Some(Code::ReadWrite), - "Select completed", - ).map_err(Error::msg)?), - ], tr)) + Ok(( + vec![ + ImapRes::Data(Data::Exists(0)), + ImapRes::Data(Data::Recent(0)), + ImapRes::Data(Data::Flags(vec![])), + /*ImapRes::Status(), + ImapRes::Status(), + ImapRes::Status(),*/ + ImapRes::Status( + Status::ok( + Some(self.tag.clone()), + Some(Code::ReadWrite), + "Select completed", + ) + .map_err(Error::msg)?, + ), + ], + tr, + )) } } |