Hook up auth
This commit is contained in:
parent
08d2e8c4b4
commit
6f504dc71c
9 changed files with 69 additions and 30 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1130,6 +1130,7 @@ dependencies = [
|
|||
"maplit",
|
||||
"nom",
|
||||
"panorama-proto-common",
|
||||
"serde",
|
||||
"stderrlog",
|
||||
"tokio",
|
||||
"tokio-rustls 0.23.1",
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue