From d3f8a6627ca13a020bac9936d1f40a18239b6d6d Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Mon, 27 Jun 2022 11:40:45 +0200 Subject: Add support for flags --- src/imap/command/authenticated.rs | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'src/imap') diff --git a/src/imap/command/authenticated.rs b/src/imap/command/authenticated.rs index f2d7c21..5924f53 100644 --- a/src/imap/command/authenticated.rs +++ b/src/imap/command/authenticated.rs @@ -1,7 +1,8 @@ use anyhow::{anyhow, Error, Result}; use boitalettres::proto::Response; use imap_codec::types::command::CommandBody; -use imap_codec::types::core::Tag; +use imap_codec::types::core::{Atom, Tag}; +use imap_codec::types::flag::Flag; use imap_codec::types::mailbox::{ListMailbox, Mailbox as MailboxCodec}; use imap_codec::types::response::{Code, Data, Response as ImapRes, Status}; @@ -10,6 +11,14 @@ use crate::imap::flow; use crate::imap::session::InnerContext; use crate::mailbox::Mailbox; +const DEFAULT_FLAGS: [Flag; 5] = [ + Flag::Seen, + Flag::Answered, + Flag::Flagged, + Flag::Deleted, + Flag::Draft, +]; + pub async fn dispatch<'a>( inner: InnerContext<'a>, user: &'a flow::User, @@ -114,7 +123,6 @@ impl<'a> StateContext<'a> { "First unseen UID", ) .map_err(Error::msg)?; - //let r_permanentflags = Status::ok(None, Some(Code:: let mut res = Vec::::new(); @@ -122,7 +130,21 @@ impl<'a> StateContext<'a> { res.push(ImapRes::Data(Data::Recent(sum.recent))); - res.push(ImapRes::Data(Data::Flags(vec![]))); + let mut flags: Vec = sum.flags.map(|f| match f.chars().next() { + Some('\\') => None, + Some('$') if f == "$unseen" => None, + Some(_) => match Atom::try_from(f.clone()) { + Err(_) => { + tracing::error!(username=%self.user.name, mailbox=%name, flag=%f, "Unable to encode flag as IMAP atom"); + None + }, + Ok(a) => Some(Flag::Keyword(a)), + }, + None => None, + }).flatten().collect(); + flags.extend_from_slice(&DEFAULT_FLAGS); + + res.push(ImapRes::Data(Data::Flags(flags.clone()))); let uid_validity = Status::ok( None, @@ -149,6 +171,14 @@ impl<'a> StateContext<'a> { res.push(ImapRes::Status(status_unseen)); } + flags.push(Flag::Permanent); + let permanent_flags = Status::ok( + None, + Some(Code::PermanentFlags(flags)), + "Flags permitted", + ).map_err(Error::msg)?; + res.push(ImapRes::Status(permanent_flags)); + let last = Status::ok( Some(self.tag.clone()), Some(Code::ReadWrite), -- cgit v1.2.3