feat: ignore client-supplied POP3 credentials
Build and publish container / build (pull_request) Successful in 9m23s

POP3 clients may be required to send USER/PASS, but the proxy never uses
them. Accept any client credentials blindly and always authenticate to the
IMAP backend with the configured BACKEND_IMAP_USER / BACKEND_IMAP_PASS.

Remove the previous fallback that connected to the backend using
client-supplied credentials when backend credentials were unset; the proxy
now raises a clear configuration error in that case.

Add tests covering that client credentials are ignored and that missing
backend credentials are reported.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Emma Thorpe
2026-06-17 18:07:25 +01:00
parent e51740b8db
commit 78a3c21ac7
2 changed files with 60 additions and 16 deletions
+43
View File
@@ -227,6 +227,49 @@ def test_top_returns_headers_and_limited_body():
assert output.endswith(b".\r\n")
def test_authenticate_ignores_client_credentials(monkeypatch):
captured = {}
def fake_login(self):
captured["username"] = self.username
captured["password"] = self.password
monkeypatch.setattr(IMAPBackend, "login", fake_login)
monkeypatch.setattr(IMAPBackend, "list_uids", lambda self: [])
previous_user = Settings.BACKEND_IMAP_USER
previous_pass = Settings.BACKEND_IMAP_PASS
Settings.BACKEND_IMAP_USER = "backend-user"
Settings.BACKEND_IMAP_PASS = "backend-pass"
session = POP3Session(None, FakeWriter())
session.username = "client-user"
session.password = "client-pass"
session.authenticate()
# The proxy must connect with its own credentials, never the client's.
assert captured["username"] == "backend-user"
assert captured["password"] == "backend-pass"
Settings.BACKEND_IMAP_USER = previous_user
Settings.BACKEND_IMAP_PASS = previous_pass
def test_authenticate_requires_backend_credentials(monkeypatch):
previous_user = Settings.BACKEND_IMAP_USER
previous_pass = Settings.BACKEND_IMAP_PASS
Settings.BACKEND_IMAP_USER = None
Settings.BACKEND_IMAP_PASS = None
session = POP3Session(None, FakeWriter())
session.username = "client-user"
session.password = "client-pass"
with pytest.raises(RuntimeError, match="Backend IMAP credentials are not configured"):
session.authenticate()
Settings.BACKEND_IMAP_USER = previous_user
Settings.BACKEND_IMAP_PASS = previous_pass
def test_dele_survives_stat_list_uidl_until_quit():
session = make_session([b"1", b"2", b"3"])
asyncio.run(session.handle_dele(["2"]))