Hook up auth

This commit is contained in:
Michael Zhang 2021-11-04 14:30:59 -05:00
parent 08d2e8c4b4
commit 6f504dc71c
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
9 changed files with 69 additions and 30 deletions

1
Cargo.lock generated
View file

@ -1130,6 +1130,7 @@ dependencies = [
"maplit",
"nom",
"panorama-proto-common",
"serde",
"stderrlog",
"tokio",
"tokio-rustls 0.23.1",

View file

@ -9,6 +9,7 @@ use std::io::Read;
use std::path::{Path, PathBuf};
use anyhow::Result;
use panorama_imap::client::auth::ImapAuth;
#[cfg(feature = "config-watch")]
pub use self::watcher::{spawn_config_watcher_system, ConfigWatcher};
@ -62,21 +63,6 @@ pub struct ImapConfig {
pub auth: ImapAuth,
}
/// Method of authentication for the IMAP server
#[derive(Serialize, Deserialize, Clone, Derivative)]
#[derivative(Debug)]
#[serde(tag = "auth")]
pub enum ImapAuth {
/// Use plain username/password authentication
#[serde(rename = "plain")]
Plain {
username: String,
#[derivative(Debug = "ignore")]
password: String,
},
}
/// Describes when to perform the TLS handshake
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum TlsMethod {

View file

@ -49,9 +49,11 @@ pub async fn mail_main(
.tls(matches!(acct.imap.tls, TlsMethod::On))
.build()?;
let pool_config = PoolConfig {
auth_config: acct.imap.auth,
client_config,
max_connections: 10,
};
let pool = ImapPool::new(client_config, pool_config);
let pool = ImapPool::new(pool_config);
// grab one connection from that pool and start running a background
// synchronization thread

View file

@ -13,8 +13,9 @@ readme = "README.md"
workspace = ".."
[features]
default = ["pool", "rfc2177", "rfc6154"]
default = ["serialize", "pool", "rfc2177", "rfc6154"]
low-level = []
serialize = ["serde/derive"]
pool = ["crossbeam"]
rfc2087 = [] # quota
rfc2177 = [] # idle
@ -41,10 +42,12 @@ tokio-util = { version = "0.6.9", features = ["codec"] }
webpki-roots = "0.22.1"
panorama-proto-common = { path = "../proto-common" }
crossbeam = { version = "0.8.1", optional = true }
# for fuzzing
arbitrary = { version = "1.0.2", optional = true, features = ["derive"] }
crossbeam = { version = "0.8.1", optional = true }
serde = { version = "1.0.130", optional = true }
[dev-dependencies]
maplit = "1.0.2"

View file

@ -4,8 +4,46 @@ use anyhow::Result;
use panorama_proto_common::Bytes;
use crate::client::inner::Inner;
use crate::interface::ImapClient;
use crate::proto::command::{Command, CommandLogin};
/// Method of authentication for the IMAP server
#[cfg_attr(
feature = "serialize",
derive(Serialize, Deserialize, Clone, Derivative)
)]
#[derivative(Debug)]
#[serde(tag = "auth")]
pub enum ImapAuth {
/// Use plain username/password authentication
#[serde(rename = "plain")]
Plain {
username: String,
#[derivative(Debug = "ignore")]
password: String,
},
}
impl ImapAuth {
pub async fn perform_auth<C>(&self, inner: &mut Inner<C>) -> Result<()>
where
C: Client,
{
match self {
ImapAuth::Plain { username, password } => {
let command = Command::Login(CommandLogin {
userid: Bytes::from(username.clone()),
password: Bytes::from(password.clone()),
});
let result = inner.execute(command).await?;
todo!()
}
}
}
}
pub trait Client:
AsyncRead + AsyncWrite + Unpin + Sync + Send + 'static
{

View file

@ -22,7 +22,7 @@ use crate::proto::{
},
};
use super::auth::AuthMethod;
use super::auth::{AuthMethod, ImapAuth};
use super::inner::Inner;
use super::response_stream::ResponseStream;
use super::tls::wrap_tls;
@ -102,10 +102,7 @@ impl ClientUnauthenticated {
}
}
pub async fn auth(
self,
auth: impl AuthMethod,
) -> Result<ClientAuthenticated> {
pub async fn auth(self, auth: &ImapAuth) -> Result<ClientAuthenticated> {
match self {
// this is a no-op, we don't need to upgrade
ClientUnauthenticated::Encrypted(mut inner) => {

View file

@ -1,6 +1,9 @@
use anyhow::Result;
use crate::proto::response::Envelope;
use crate::proto::{
command::Command,
response::{Envelope, Response},
};
#[async_trait]
pub trait ImapClient {

View file

@ -15,6 +15,10 @@ extern crate log;
#[macro_use]
extern crate panorama_proto_common;
#[cfg(feature = "serialize")]
#[macro_use]
extern crate serde;
#[cfg(test)]
#[macro_use]
extern crate maplit;

View file

@ -4,7 +4,11 @@ use anyhow::Result;
use crossbeam::queue::ArrayQueue;
use tokio::sync::Semaphore;
use crate::{client::auth::{AuthMethod, Login}, interface::ImapClient, proto::response::Envelope};
use crate::{
client::auth::{ImapAuth, Login},
interface::ImapClient,
proto::response::Envelope,
};
use super::client::{ClientAuthenticated, Config, ConfigBuilder};
@ -12,6 +16,7 @@ use super::client::{ClientAuthenticated, Config, ConfigBuilder};
pub struct PoolConfig {
pub max_connections: usize,
pub client_config: Config,
pub auth_config: ImapAuth,
}
/// A pool of IMAP connections.
@ -49,10 +54,11 @@ pub struct InnerPool {
impl InnerPool {
pub fn init(config: PoolConfig) -> Self {
let max_connections = config.max_connections;
InnerPool {
config,
semaphore: Semaphore::new(config.max_connections),
connections: ArrayQueue::new(config.max_connections),
semaphore: Semaphore::new(max_connections),
connections: ArrayQueue::new(max_connections),
}
}
@ -75,8 +81,7 @@ impl InnerPool {
debug!("Client connected to {}", self.config.client_config.hostname);
// authenticate
let client_auth = client.auth(Login {
});
let client_auth = client.auth(&self.config.auth_config);
}
};