get delivery working

This commit is contained in:
missytake
2026-04-15 12:39:28 +02:00
committed by holger krekel
parent e46fd6a78d
commit 175a5ad700
8 changed files with 29 additions and 17 deletions

View File

@@ -95,7 +95,9 @@ class Config:
self.tls_key_path = f"/var/lib/acme/live/{self.mail_domain}/privkey" self.tls_key_path = f"/var/lib/acme/live/{self.mail_domain}/privkey"
# deprecated option # deprecated option
mbdir = params.get("mailboxes_dir", f"/home/vmail/mail/{self.mail_domain}") mbdir = params.get(
"mailboxes_dir", f"/home/vmail/mail/{self.mail_domain_deliverable}"
)
self.mailboxes_dir = Path(mbdir.strip()) self.mailboxes_dir = Path(mbdir.strip())
# old unused option (except for first migration from sqlite to maildir store) # old unused option (except for first migration from sqlite to maildir store)

View File

@@ -108,7 +108,7 @@ class AuthDictProxy(DictProxy):
if namespace == "shared": if namespace == "shared":
if type == "userdb": if type == "userdb":
user = args[0] user = args[0]
if user.endswith(f"@{config.mail_domain}"): if user.endswith(f"@{config.mail_domain_deliverable}"):
res = self.lookup_userdb(user) res = self.lookup_userdb(user)
if res: if res:
reply_command = "O" reply_command = "O"
@@ -116,7 +116,7 @@ class AuthDictProxy(DictProxy):
reply_command = "N" reply_command = "N"
elif type == "passdb": elif type == "passdb":
user = args[1] user = args[1]
if user.endswith(f"@{config.mail_domain}"): if user.endswith(f"@{config.mail_domain_deliverable}"):
res = self.lookup_passdb(user, cleartext_password=args[0]) res = self.lookup_passdb(user, cleartext_password=args[0])
if res: if res:
reply_command = "O" reply_command = "O"

View File

@@ -13,6 +13,7 @@ def test_read_config_basic(example_config):
example_config = read_config(inipath) example_config = read_config(inipath)
assert example_config.max_user_send_per_minute == 37 assert example_config.max_user_send_per_minute == 37
assert example_config.mail_domain == "chat.example.org" assert example_config.mail_domain == "chat.example.org"
assert example_config.mail_domain_deliverable == "chat.example.org"
def test_read_config_basic_using_defaults(tmp_path, maildomain): def test_read_config_basic_using_defaults(tmp_path, maildomain):

View File

@@ -44,12 +44,20 @@ def test_invalid_username_length(example_config):
config.username_min_length = 6 config.username_min_length = 6
config.username_max_length = 10 config.username_max_length = 10
password = create_newemail_dict(config)["password"] password = create_newemail_dict(config)["password"]
assert not is_allowed_to_create(config, f"a1234@{config.mail_domain}", password)
assert is_allowed_to_create(config, f"012345@{config.mail_domain}", password)
assert is_allowed_to_create(config, f"0123456@{config.mail_domain}", password)
assert is_allowed_to_create(config, f"0123456789@{config.mail_domain}", password)
assert not is_allowed_to_create( assert not is_allowed_to_create(
config, f"0123456789x@{config.mail_domain}", password config, f"a1234@{config.mail_domain_deliverable}", password
)
assert is_allowed_to_create(
config, f"012345@{config.mail_domain_deliverable}", password
)
assert is_allowed_to_create(
config, f"0123456@{config.mail_domain_deliverable}", password
)
assert is_allowed_to_create(
config, f"0123456789@{config.mail_domain_deliverable}", password
)
assert not is_allowed_to_create(
config, f"0123456789x@{config.mail_domain_deliverable}", password
) )
@@ -124,7 +132,7 @@ def test_invalid_localpart_characters(make_config):
"""Test that is_allowed_to_create rejects localparts with invalid characters.""" """Test that is_allowed_to_create rejects localparts with invalid characters."""
config = make_config("chat.example.org", {"username_min_length": "3"}) config = make_config("chat.example.org", {"username_min_length": "3"})
password = "zequ0Aimuchoodaechik" password = "zequ0Aimuchoodaechik"
domain = config.mail_domain domain = config.mail_domain_deliverable
# valid localparts # valid localparts
assert is_allowed_to_create(config, f"abc123@{domain}", password) assert is_allowed_to_create(config, f"abc123@{domain}", password)

View File

@@ -56,7 +56,7 @@ def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir, example_conf
assert lines[0] == "Content-Type: application/json" assert lines[0] == "Content-Type: application/json"
assert not lines[1] assert not lines[1]
dic = json.loads(lines[2]) dic = json.loads(lines[2])
assert dic["email"].endswith(f"@{example_config.mail_domain}") assert dic["email"].endswith(f"@{example_config.mail_domain_deliverable}")
assert len(dic["password"]) >= 10 assert len(dic["password"]) >= 10
# default tls_cert=acme should not include dclogin_url # default tls_cert=acme should not include dclogin_url
assert "dclogin_url" not in dic assert "dclogin_url" not in dic

View File

@@ -384,7 +384,7 @@ class ChatmailDeployer(Deployer):
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
self.mail_domain = config.mail_domain self.mail_domain_deliverable = config.mail_domain_deliverable
def install(self): def install(self):
self.put_file( self.put_file(
@@ -417,7 +417,7 @@ class ChatmailDeployer(Deployer):
server.shell( server.shell(
name="Setup /etc/mailname", name="Setup /etc/mailname",
commands=[ commands=[
f"echo {self.mail_domain} >/etc/mailname; chmod 644 /etc/mailname" f"echo {self.mail_domain_deliverable} >/etc/mailname; chmod 644 /etc/mailname"
], ],
) )
@@ -470,6 +470,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
config = read_config(config_path) config = read_config(config_path)
check_config(config) check_config(config)
mail_domain = config.mail_domain mail_domain = config.mail_domain
mail_domain_deliverable = config.mail_domain_deliverable
if website_only: if website_only:
Deployment().perform_stages([WebsiteDeployer(config)]) Deployment().perform_stages([WebsiteDeployer(config)])
@@ -540,7 +541,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
WebsiteDeployer(config), WebsiteDeployer(config),
ChatmailVenvDeployer(config), ChatmailVenvDeployer(config),
MtastsDeployer(), MtastsDeployer(),
OpendkimDeployer(mail_domain), OpendkimDeployer(mail_domain_deliverable),
# Dovecot should be started before Postfix # Dovecot should be started before Postfix
# because it creates authentication socket # because it creates authentication socket
# required by Postfix. # required by Postfix.

View File

@@ -40,7 +40,7 @@ service imap {
process_limit = 50000 process_limit = 50000
} }
mail_server_admin = mailto:root@{{ config.mail_domain }} mail_server_admin = mailto:root@{{ config.mail_domain_deliverable }}
mail_server_comment = Chatmail server mail_server_comment = Chatmail server
# `zlib` enables compressing messages stored in the maildir. # `zlib` enables compressing messages stored in the maildir.

View File

@@ -12,8 +12,8 @@ from cmdeploy.basedeploy import Deployer
class OpendkimDeployer(Deployer): class OpendkimDeployer(Deployer):
required_users = [("opendkim", None, ["opendkim"])] required_users = [("opendkim", None, ["opendkim"])]
def __init__(self, mail_domain): def __init__(self, mail_domain_deliverable):
self.mail_domain = mail_domain self.mail_domain_deliverable = mail_domain_deliverable
def install(self): def install(self):
apt.packages( apt.packages(
@@ -22,7 +22,7 @@ class OpendkimDeployer(Deployer):
) )
def configure(self): def configure(self):
domain = self.mail_domain domain = self.mail_domain_deliverable
dkim_selector = "opendkim" dkim_selector = "opendkim"
"""Configures OpenDKIM""" """Configures OpenDKIM"""