aboutsummaryrefslogtreecommitdiff
path: root/src/server.rs
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2022-06-15 18:40:39 +0200
committerQuentin Dufour <quentin@deuxfleurs.fr>2022-06-15 18:40:39 +0200
commit6b5b53916efb4897643172fdf461291b4effcf48 (patch)
tree9030270809e8b2fd56bc91b19d82915ea8c85641 /src/server.rs
parent2bbcb119c437a3d8ba5d747f76898faa5ad32d93 (diff)
parent0700e27127e4644dbd323b9a22d994209143fa2a (diff)
downloadaerogramme-6b5b53916efb4897643172fdf461291b4effcf48.tar.gz
aerogramme-6b5b53916efb4897643172fdf461291b4effcf48.zip
Add LMTP support
Diffstat (limited to 'src/server.rs')
-rw-r--r--src/server.rs107
1 files changed, 87 insertions, 20 deletions
diff --git a/src/server.rs b/src/server.rs
index 365bc0f..3abdfd1 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -1,40 +1,107 @@
-use anyhow::Result;
use std::sync::Arc;
-use crate::config::*;
-use crate::mailstore;
-use crate::service;
+
use boitalettres::server::accept::addr::AddrIncoming;
+use boitalettres::server::accept::addr::AddrStream;
use boitalettres::server::Server as ImapServer;
+use anyhow::{bail, Result};
+use futures::{try_join, StreamExt};
+use log::*;
+use rusoto_signature::Region;
+use tokio::sync::watch;
+use tower::Service;
+
+use crate::mailstore;
+use crate::service;
+use crate::lmtp::*;
+use crate::config::*;
+use crate::login::{ldap_provider::*, static_provider::*, *};
+use crate::mailbox::Mailbox;
+
pub struct Server {
- pub incoming: AddrIncoming,
- pub mailstore: Arc<mailstore::Mailstore>,
+ lmtp_server: Option<Arc<LmtpServer>>,
+ imap_server: ImapServer<AddrIncoming, service::Instance>,
}
+
impl Server {
pub async fn new(config: Config) -> Result<Self> {
+ let lmtp_config = config.lmtp.clone(); //@FIXME
+ let login = authenticator(config)?;
+
+ let lmtp = lmtp_config.map(|cfg| LmtpServer::new(cfg, login.clone()));
+
+ let incoming = AddrIncoming::new("127.0.0.1:4567").await?;
+ let imap = ImapServer::new(incoming).serve(service::Instance::new(login.clone()));
+
Ok(Self {
- incoming: AddrIncoming::new("127.0.0.1:4567").await?,
- mailstore: mailstore::Mailstore::new(config)?,
+ lmtp_server: lmtp,
+ imap_server: imap,
})
}
- pub async fn run(self: Self) -> Result<()> {
- tracing::info!("Starting server on {:#}", self.incoming.local_addr);
- /*let creds = self
- .mailstore
- .login_provider
- .login("quentin", "poupou")
- .await?;*/
- //let mut mailbox = Mailbox::new(&creds, "TestMailbox".to_string()).await?;
- //mailbox.test().await?;
+ pub async fn run(self) -> Result<()> {
+ //tracing::info!("Starting server on {:#}", self.imap.incoming.local_addr);
+ tracing::info!("Starting Aerogramme...");
+
+ let (exit_signal, provoke_exit) = watch_ctrl_c();
+ let exit_on_err = move |err: anyhow::Error| {
+ error!("Error: {}", err);
+ let _ = provoke_exit.send(true);
+ };
+
+
+ try_join!(async {
+ match self.lmtp_server.as_ref() {
+ None => Ok(()),
+ Some(s) => s.run(exit_signal.clone()).await,
+ }
+ },
+ //@FIXME handle ctrl + c
+ async {
+ self.imap_server.await?;
+ Ok(())
+ }
+ )?;
- let server =
- ImapServer::new(self.incoming).serve(service::Instance::new(self.mailstore.clone()));
- let _ = server.await?;
Ok(())
}
}
+
+fn authenticator(config: Config) -> Result<Arc<dyn LoginProvider + Send + Sync>> {
+ let s3_region = Region::Custom {
+ name: config.aws_region.clone(),
+ endpoint: config.s3_endpoint,
+ };
+ let k2v_region = Region::Custom {
+ name: config.aws_region,
+ endpoint: config.k2v_endpoint,
+ };
+
+ let lp: Arc<dyn LoginProvider + Send + Sync> = match (config.login_static, config.login_ldap) {
+ (Some(st), None) => Arc::new(StaticLoginProvider::new(st, k2v_region, s3_region)?),
+ (None, Some(ld)) => Arc::new(LdapLoginProvider::new(ld, k2v_region, s3_region)?),
+ (Some(_), Some(_)) => {
+ bail!("A single login provider must be set up in config file")
+ }
+ (None, None) => bail!("No login provider is set up in config file"),
+ };
+ Ok(lp)
+}
+
+pub fn watch_ctrl_c() -> (watch::Receiver<bool>, Arc<watch::Sender<bool>>) {
+ let (send_cancel, watch_cancel) = watch::channel(false);
+ let send_cancel = Arc::new(send_cancel);
+ let send_cancel_2 = send_cancel.clone();
+ tokio::spawn(async move {
+ tokio::signal::ctrl_c()
+ .await
+ .expect("failed to install CTRL+C signal handler");
+ info!("Received CTRL+C, shutting down.");
+ send_cancel.send(true).unwrap();
+ });
+ (watch_cancel, send_cancel_2)
+}