From 8cde0af040dfdfd3435504a3468c17d8672a39a2 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Tue, 1 Jul 2025 10:59:21 -0400 Subject: [PATCH] email_mirror: Fail more gracefully on empty EMAIL_GATEWAY_PATTERN. Otherwise, this fails on `match.group(1)` as there is no match group. The server would ideally respond with a 521 or 556 code[^1] on initial connection, but aiosmtpd does not provide that option. [^1]: https://www.rfc-editor.org/rfc/rfc7504 --- zerver/lib/email_mirror_helpers.py | 2 ++ zerver/tests/test_email_mirror.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/zerver/lib/email_mirror_helpers.py b/zerver/lib/email_mirror_helpers.py index 6dac1fb0f6..2ef10f0b1b 100644 --- a/zerver/lib/email_mirror_helpers.py +++ b/zerver/lib/email_mirror_helpers.py @@ -33,6 +33,8 @@ class ZulipEmailForwardUserError(ZulipEmailForwardError): def get_email_gateway_message_string_from_address(address: str) -> str: + if settings.EMAIL_GATEWAY_PATTERN == "": + raise ZulipEmailForwardError("This server is not configured for incoming email.") pattern_parts = [re.escape(part) for part in settings.EMAIL_GATEWAY_PATTERN.split("%s")] if settings.EMAIL_GATEWAY_EXTRA_PATTERN_HACK: # Accept mails delivered to any Zulip server diff --git a/zerver/tests/test_email_mirror.py b/zerver/tests/test_email_mirror.py index 58037fe9a2..a5f0ba85bf 100644 --- a/zerver/tests/test_email_mirror.py +++ b/zerver/tests/test_email_mirror.py @@ -2007,6 +2007,26 @@ class TestEmailMirrorServer(ZulipTestCase): return [r.decode() for r in responses] + @override_settings(EMAIL_GATEWAY_PATTERN="") + async def test_unconfigured(self) -> None: + self.assertEqual( + await self.handler_response( + [ + "HELO localhost", + "MAIL FROM: ", + "RCPT TO: ", + "QUIT", + ] + ), + [ + "220 testhost Zulip 1.2.3\r\n", + "250 testhost\r\n", + "250 OK\r\n", + "550 5.1.1 Bad destination mailbox address: This server is not configured for incoming email.\r\n", + "221 Bye\r\n", + ], + ) + @override_settings(EMAIL_GATEWAY_PATTERN="%s@zulip.example.com") async def test_handler_error(self) -> None: with (