Allow multiple servers of same type

This commit is contained in:
Balakrishnan Balasubramanian 2023-06-23 22:03:58 -04:00
parent bcd250d2b0
commit 2bcc807b91
2 changed files with 49 additions and 43 deletions

View File

@ -41,6 +41,7 @@ class TLSCfg(Jata):
class ServerCfg(Jata): class ServerCfg(Jata):
server_type: str
host: str = "default" host: str = "default"
port: int port: int
# disabled: bool = False # disabled: bool = False
@ -48,17 +49,20 @@ class ServerCfg(Jata):
class PopCfg(ServerCfg): class PopCfg(ServerCfg):
server_type = "pop"
port = 995 port = 995
timeout_seconds = 60 timeout_seconds = 60
class SmtpStartTLSCfg(ServerCfg): class SmtpStartTLSCfg(ServerCfg):
smtputf8 = True server_type = "smtp_starttls"
smtputf8 = True # Not used yet
port = 25 port = 25
class SmtpCfg(ServerCfg): class SmtpCfg(ServerCfg):
smtputf8 = True server_type = "smtp_starttls"
smtputf8 = True # Not used yet
port = 465 port = 465
@ -77,10 +81,7 @@ class Config(Jata):
boxes: list[Mbox] boxes: list[Mbox]
users: list[User] users: list[User]
pop: PopCfg | None = None servers: list[ServerCfg]
smtp_starttls: SmtpStartTLSCfg | None = None
smtp: SmtpCfg | None = None
# smtp_port_submission = 587
CheckerFn = Callable[[str], bool] CheckerFn = Callable[[str], bool]

View File

@ -45,7 +45,7 @@ async def a_main(cfg: config.Config) -> None:
elif tls == "disable": elif tls == "disable":
return None return None
else: else:
tls_cfg = config.TLSCfg(pop.tls) tls_cfg = config.TLSCfg(tls)
return create_tls_context(tls_cfg.certfile, tls_cfg.keyfile) return create_tls_context(tls_cfg.certfile, tls_cfg.keyfile)
def get_host(host): def get_host(host):
@ -57,47 +57,52 @@ async def a_main(cfg: config.Config) -> None:
mbox_finder = config.gen_addr_to_mboxes(cfg) mbox_finder = config.gen_addr_to_mboxes(cfg)
servers: list[asyncio.Server] = [] servers: list[asyncio.Server] = []
if cfg.pop: if not cfg.servers:
pop = config.PopCfg(cfg.pop) logging.warning("Nothing to do!")
pop_server = await create_pop_server( return
host=get_host(pop.host),
port=pop.port,
mails_path=Path(cfg.mails_path),
users=cfg.users,
ssl_context=get_tls_context(pop.tls),
timeout_seconds=pop.timeout_seconds,
)
servers.append(pop_server)
if cfg.smtp_starttls: for scfg in cfg.servers:
stls = config.SmtpStartTLSCfg(cfg.smtp_starttls) if scfg.server_type == "pop":
stls_context = get_tls_context(stls.tls) pop = config.PopCfg(scfg)
if not stls_context: pop_server = await create_pop_server(
raise Exception("starttls requires ssl_context") host=get_host(pop.host),
smtp_server_starttls = await create_smtp_server_starttls( port=pop.port,
host=get_host(stls.host), mails_path=Path(cfg.mails_path),
port=stls.port, users=cfg.users,
mails_path=Path(cfg.mails_path), ssl_context=get_tls_context(pop.tls),
mbox_finder=mbox_finder, timeout_seconds=pop.timeout_seconds,
ssl_context=stls_context, )
) servers.append(pop_server)
servers.append(smtp_server_starttls) elif scfg.server_type == "smtp_starttls":
stls = config.SmtpStartTLSCfg(scfg)
if cfg.smtp: stls_context = get_tls_context(stls.tls)
smtp = config.SmtpCfg(cfg.smtp) if not stls_context:
smtp_server = await create_smtp_server( raise Exception("starttls requires ssl_context")
host=get_host(smtp.host), smtp_server_starttls = await create_smtp_server_starttls(
port=smtp.port, host=get_host(stls.host),
mails_path=Path(cfg.mails_path), port=stls.port,
mbox_finder=mbox_finder, mails_path=Path(cfg.mails_path),
ssl_context=get_tls_context(smtp.tls), mbox_finder=mbox_finder,
) ssl_context=stls_context,
servers.append(smtp_server) )
servers.append(smtp_server_starttls)
elif scfg.server_type == "smtp":
smtp = config.SmtpCfg(scfg)
smtp_server = await create_smtp_server(
host=get_host(smtp.host),
port=smtp.port,
mails_path=Path(cfg.mails_path),
mbox_finder=mbox_finder,
ssl_context=get_tls_context(smtp.tls),
)
servers.append(smtp_server)
else:
logging.error(f"Unknown server {scfg.server_type=}")
if servers: if servers:
await asyncio.gather(*[server.serve_forever() for server in servers]) await asyncio.gather(*[server.serve_forever() for server in servers])
else: else:
logging.warn("Nothing to do!") logging.warning("Nothing to do!")
def main() -> None: def main() -> None: