From 175a5ad700cfe05e08bc7f59bfca8a94045a9f94 Mon Sep 17 00:00:00 2001 From: missytake Date: Wed, 15 Apr 2026 12:39:28 +0200 Subject: [PATCH] get delivery working --- chatmaild/src/chatmaild/config.py | 4 +++- chatmaild/src/chatmaild/doveauth.py | 4 ++-- chatmaild/src/chatmaild/tests/test_config.py | 1 + .../src/chatmaild/tests/test_doveauth.py | 20 +++++++++++++------ chatmaild/src/chatmaild/tests/test_newmail.py | 2 +- cmdeploy/src/cmdeploy/deployers.py | 7 ++++--- cmdeploy/src/cmdeploy/dovecot/dovecot.conf.j2 | 2 +- cmdeploy/src/cmdeploy/opendkim/deployer.py | 6 +++--- 8 files changed, 29 insertions(+), 17 deletions(-) diff --git a/chatmaild/src/chatmaild/config.py b/chatmaild/src/chatmaild/config.py index c467e3f2..76e736eb 100644 --- a/chatmaild/src/chatmaild/config.py +++ b/chatmaild/src/chatmaild/config.py @@ -95,7 +95,9 @@ class Config: self.tls_key_path = f"/var/lib/acme/live/{self.mail_domain}/privkey" # 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()) # old unused option (except for first migration from sqlite to maildir store) diff --git a/chatmaild/src/chatmaild/doveauth.py b/chatmaild/src/chatmaild/doveauth.py index 314e7348..b0410400 100644 --- a/chatmaild/src/chatmaild/doveauth.py +++ b/chatmaild/src/chatmaild/doveauth.py @@ -108,7 +108,7 @@ class AuthDictProxy(DictProxy): if namespace == "shared": if type == "userdb": user = args[0] - if user.endswith(f"@{config.mail_domain}"): + if user.endswith(f"@{config.mail_domain_deliverable}"): res = self.lookup_userdb(user) if res: reply_command = "O" @@ -116,7 +116,7 @@ class AuthDictProxy(DictProxy): reply_command = "N" elif type == "passdb": 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]) if res: reply_command = "O" diff --git a/chatmaild/src/chatmaild/tests/test_config.py b/chatmaild/src/chatmaild/tests/test_config.py index bccea318..f23928e3 100644 --- a/chatmaild/src/chatmaild/tests/test_config.py +++ b/chatmaild/src/chatmaild/tests/test_config.py @@ -13,6 +13,7 @@ def test_read_config_basic(example_config): example_config = read_config(inipath) assert example_config.max_user_send_per_minute == 37 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): diff --git a/chatmaild/src/chatmaild/tests/test_doveauth.py b/chatmaild/src/chatmaild/tests/test_doveauth.py index 3b18d97d..eb86b307 100644 --- a/chatmaild/src/chatmaild/tests/test_doveauth.py +++ b/chatmaild/src/chatmaild/tests/test_doveauth.py @@ -44,12 +44,20 @@ def test_invalid_username_length(example_config): config.username_min_length = 6 config.username_max_length = 10 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( - 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.""" config = make_config("chat.example.org", {"username_min_length": "3"}) password = "zequ0Aimuchoodaechik" - domain = config.mail_domain + domain = config.mail_domain_deliverable # valid localparts assert is_allowed_to_create(config, f"abc123@{domain}", password) diff --git a/chatmaild/src/chatmaild/tests/test_newmail.py b/chatmaild/src/chatmaild/tests/test_newmail.py index f7046ca3..6e509712 100644 --- a/chatmaild/src/chatmaild/tests/test_newmail.py +++ b/chatmaild/src/chatmaild/tests/test_newmail.py @@ -56,7 +56,7 @@ def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir, example_conf assert lines[0] == "Content-Type: application/json" assert not lines[1] 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 # default tls_cert=acme should not include dclogin_url assert "dclogin_url" not in dic diff --git a/cmdeploy/src/cmdeploy/deployers.py b/cmdeploy/src/cmdeploy/deployers.py index 292d64bc..056838f8 100644 --- a/cmdeploy/src/cmdeploy/deployers.py +++ b/cmdeploy/src/cmdeploy/deployers.py @@ -384,7 +384,7 @@ class ChatmailDeployer(Deployer): def __init__(self, config): self.config = config - self.mail_domain = config.mail_domain + self.mail_domain_deliverable = config.mail_domain_deliverable def install(self): self.put_file( @@ -417,7 +417,7 @@ class ChatmailDeployer(Deployer): server.shell( name="Setup /etc/mailname", 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) check_config(config) mail_domain = config.mail_domain + mail_domain_deliverable = config.mail_domain_deliverable if website_only: Deployment().perform_stages([WebsiteDeployer(config)]) @@ -540,7 +541,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) - WebsiteDeployer(config), ChatmailVenvDeployer(config), MtastsDeployer(), - OpendkimDeployer(mail_domain), + OpendkimDeployer(mail_domain_deliverable), # Dovecot should be started before Postfix # because it creates authentication socket # required by Postfix. diff --git a/cmdeploy/src/cmdeploy/dovecot/dovecot.conf.j2 b/cmdeploy/src/cmdeploy/dovecot/dovecot.conf.j2 index a7ce7b62..ddfa65a2 100644 --- a/cmdeploy/src/cmdeploy/dovecot/dovecot.conf.j2 +++ b/cmdeploy/src/cmdeploy/dovecot/dovecot.conf.j2 @@ -40,7 +40,7 @@ service imap { 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 # `zlib` enables compressing messages stored in the maildir. diff --git a/cmdeploy/src/cmdeploy/opendkim/deployer.py b/cmdeploy/src/cmdeploy/opendkim/deployer.py index 27b3876a..2417df11 100644 --- a/cmdeploy/src/cmdeploy/opendkim/deployer.py +++ b/cmdeploy/src/cmdeploy/opendkim/deployer.py @@ -12,8 +12,8 @@ from cmdeploy.basedeploy import Deployer class OpendkimDeployer(Deployer): required_users = [("opendkim", None, ["opendkim"])] - def __init__(self, mail_domain): - self.mail_domain = mail_domain + def __init__(self, mail_domain_deliverable): + self.mail_domain_deliverable = mail_domain_deliverable def install(self): apt.packages( @@ -22,7 +22,7 @@ class OpendkimDeployer(Deployer): ) def configure(self): - domain = self.mail_domain + domain = self.mail_domain_deliverable dkim_selector = "opendkim" """Configures OpenDKIM"""