diff options
author | Quentin Dufour <quentin@deuxfleurs.fr> | 2022-06-17 18:39:36 +0200 |
---|---|---|
committer | Quentin Dufour <quentin@deuxfleurs.fr> | 2022-06-17 18:39:36 +0200 |
commit | 5dd5ae8bcd6f88703bc483d7f8d5882fefad4e7e (patch) | |
tree | 312708a97fcfcd273481f41b8bd6c878030573f4 /src/imap/command/anonymous.rs | |
parent | 41f1b02171cee36706d30cf24329ff12780d47fd (diff) | |
download | aerogramme-5dd5ae8bcd6f88703bc483d7f8d5882fefad4e7e.tar.gz aerogramme-5dd5ae8bcd6f88703bc483d7f8d5882fefad4e7e.zip |
WIP Refactor, code is broken
Diffstat (limited to 'src/imap/command/anonymous.rs')
-rw-r--r-- | src/imap/command/anonymous.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/imap/command/anonymous.rs b/src/imap/command/anonymous.rs new file mode 100644 index 0000000..e4222f7 --- /dev/null +++ b/src/imap/command/anonymous.rs @@ -0,0 +1,60 @@ + +use boitalettres::proto::{Request, Response}; +use crate::login::ArcLoginProvider; +use crate::imap::Context; + +//--- dispatching + +pub async fn dispatch(ctx: Context) -> Result<Response> { + match ctx.req.body { + CommandBody::Capability => anonymous::capability(ctx).await, + CommandBody::Login { username, password } => anonymous::login(ctx, username, password).await, + _ => Status::no(Some(ctx.req.tag.clone()), None, "This command is not available in the ANONYMOUS state.") + .map(|s| vec![ImapRes::Status(s)]) + .map_err(Error::msg), + } +} + +//--- Command controllers + +pub async fn capability(ctx: Context) -> Result<Response> { + let capabilities = vec![Capability::Imap4Rev1, Capability::Idle]; + let res = vec![ + ImapRes::Data(Data::Capability(capabilities)), + ImapRes::Status( + Status::ok(Some(ctx.req.tag.clone()), None, "Server capabilities") + .map_err(Error::msg)?, + ), + ]; + Ok(res) +} + +pub async fn login(ctx: Context, username: AString, password: AString) -> Result<Response> { + let (u, p) = (String::try_from(username)?, String::try_from(password)?); + tracing::info!(user = %u, "command.login"); + + let creds = match ctx.login_provider.login(&u, &p).await { + Err(e) => { + tracing::debug!(error=%e, "authentication failed"); + return Ok(vec![ImapRes::Status( + Status::no(Some(ctx.req.tag.clone()), None, "Authentication failed") + .map_err(Error::msg)?, + )]); + } + Ok(c) => c, + }; + + let user = flow::User { + creds, + name: u.clone(), + }; + ctx.state.authenticate(user)?; + + tracing::info!(username=%u, "connected"); + Ok(vec![ + //@FIXME we could send a capability status here too + ImapRes::Status( + Status::ok(Some(ctx.req.tag.clone()), None, "completed").map_err(Error::msg)?, + ), + ]) +} |