work on prototypes

This commit is contained in:
Alex 2022-06-29 13:41:05 +02:00
parent 1bc109df72
commit 8b7eb1ca91
Signed by: lx
GPG key ID: 0E496D15096376BE
8 changed files with 50 additions and 27 deletions

View file

@ -1,12 +1,12 @@
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use boitalettres::proto::{res::body::Data as Body, Request, Response}; use boitalettres::proto::{res::body::Data as Body, Request, Response};
use imap_codec::types::command::CommandBody; 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 imap_codec::types::response::{Capability, Data, Status};
use crate::imap::flow; use crate::imap::flow;
use crate::mail::user::User;
use crate::login::ArcLoginProvider; use crate::login::ArcLoginProvider;
use crate::mail::user::User;
//--- dispatching //--- dispatching

View file

@ -96,7 +96,7 @@ impl<'a> AuthenticatedContext<'a> {
async fn select(self, mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> { async fn select(self, mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> {
let name = String::try_from(mailbox.clone())?; 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"); tracing::info!(username=%self.user.username, mailbox=%name, "mailbox.selected");
let sum = mb.summary().await?; let sum = mb.summary().await?;

View file

@ -1,4 +1,4 @@
use anyhow::{Result}; use anyhow::Result;
use boitalettres::proto::Request; use boitalettres::proto::Request;
use boitalettres::proto::Response; use boitalettres::proto::Response;
use imap_codec::types::command::CommandBody; use imap_codec::types::command::CommandBody;

View file

@ -4,7 +4,6 @@ use std::fmt;
use crate::mail::mailbox::Mailbox; use crate::mail::mailbox::Mailbox;
use crate::mail::user::User; use crate::mail::user::User;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
ForbiddenTransition, ForbiddenTransition,

View file

@ -2,14 +2,14 @@ use std::collections::HashMap;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::{pin::Pin, sync::Arc}; use std::{pin::Pin, sync::Arc};
use anyhow::{Result}; use anyhow::Result;
use async_trait::async_trait; use async_trait::async_trait;
use duplexify::Duplex; use duplexify::Duplex;
use futures::{io, AsyncRead, AsyncReadExt, AsyncWrite}; use futures::{io, AsyncRead, AsyncReadExt, AsyncWrite};
use futures::{stream, stream::FuturesUnordered, StreamExt}; use futures::{stream, stream::FuturesUnordered, StreamExt};
use log::*; use log::*;
use rusoto_s3::{PutObjectRequest, S3}; use rusoto_s3::{PutObjectRequest, S3};
use tokio::net::{TcpListener}; use tokio::net::TcpListener;
use tokio::select; use tokio::select;
use tokio::sync::watch; use tokio::sync::watch;
use tokio_util::compat::*; use tokio_util::compat::*;

View file

@ -19,6 +19,7 @@ pub struct Summary<'a> {
pub flags: FlagIter<'a>, pub flags: FlagIter<'a>,
pub unseen: Option<&'a ImapUid>, pub unseen: Option<&'a ImapUid>,
} }
impl std::fmt::Display for Summary<'_> { impl std::fmt::Display for Summary<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(
@ -44,14 +45,14 @@ pub struct Mailbox {
} }
impl Mailbox { impl Mailbox {
pub(super) fn new(creds: &Credentials, name: String) -> Result<Self> { pub(super) fn new(creds: &Credentials, name: &str) -> Result<Self> {
let index_path = format!("index/{}", name); let index_path = format!("index/{}", name);
let mail_path = format!("mail/{}", name); let mail_path = format!("mail/{}", name);
let uid_index = Bayou::<UidIndex>::new(creds, index_path)?; let uid_index = Bayou::<UidIndex>::new(creds, index_path)?;
Ok(Self { Ok(Self {
bucket: creds.bucket().to_string(), 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(), key: creds.keys.master.clone(),
k2v: creds.k2v_client()?, k2v: creds.k2v_client()?,
s3: creds.s3_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<Summary> { pub async fn summary(&mut self) -> Result<Summary> {
self.uid_index.sync().await?; self.uid_index.sync().await?;
let state = self.uid_index.state(); 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<()> { pub async fn append(&mut self, _msg: IMF) -> Result<()> {
Ok(()) unimplemented!()
} }
// Copy an email from an external to this mailbox /// Copy an email from an other Mailbox to this mailbox
// @FIXME is it needed or could we implement it with append? /// (use this when possible, as it allows for a certain number of storage optimizations)
pub async fn copy(&mut self, _mailbox: String, _uid: ImapUid) -> Result<()> { pub async fn copy(&mut self, _from: &Mailbox, _uid: ImapUid) -> Result<()> {
Ok(()) unimplemented!()
} }
// Delete all emails with the \Delete flag in the mailbox /// Delete all emails with the \Delete flag in the mailbox
// Can be called by CLOSE and EXPUNGE /// Can be called by CLOSE and EXPUNGE
// @FIXME do we want to implement this feature or a simpler "delete" command /// @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? /// The controller could then "fetch \Delete" and call delete on each email?
pub async fn expunge(&mut self) -> Result<()> { 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<()> { pub async fn store(&mut self) -> Result<()> {
Ok(()) unimplemented!()
} }
pub async fn fetch(&mut self) -> Result<()> { pub async fn fetch(&mut self) -> Result<()> {
Ok(()) unimplemented!()
} }
// ----
pub async fn test(&mut self) -> Result<()> { pub async fn test(&mut self) -> Result<()> {
self.uid_index.sync().await?; self.uid_index.sync().await?;

View file

@ -1,7 +1,7 @@
pub mod mail_ident; pub mod mail_ident;
pub mod user;
pub mod mailbox; pub mod mailbox;
mod uidindex; mod uidindex;
pub mod user;
use std::convert::TryFrom; use std::convert::TryFrom;

View file

@ -25,7 +25,28 @@ impl User {
}) })
} }
pub fn open_mailbox(&self, name: String) -> Result<Mailbox> { /// Lists user's available mailboxes
Mailbox::new(&self.creds, name) pub fn list_mailboxes(&self) -> Result<Vec<String>> {
unimplemented!()
}
/// Opens an existing mailbox given its IMAP name.
pub fn open_mailbox(&self, name: &str) -> Result<Option<Mailbox>> {
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!()
} }
} }