mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-27 07:05:23 -04:00
d4cd6d60f1
The email-account endpoints coerced user-supplied ports with a bare int(data.get("imap_port") or 993), so a non-numeric port (e.g. "imap") raised ValueError and surfaced as an HTTP 500 in the create, update, and test-config endpoints.
Add a _coerce_port(value, default) -> (port, error) helper and use it in all three endpoints, returning the endpoints standard {"ok": False, "error": ...} response (matching the existing "name required" validation) instead of crashing. A blank or missing port still falls back to the default (993/465).
57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
"""User-supplied IMAP/SMTP ports must not crash the email-account endpoints.
|
|
|
|
A non-numeric port (for example ``"imap"`` or ``"993x"``) previously reached an
|
|
unguarded ``int(...)`` in create / update / test-config and raised ``ValueError``,
|
|
which surfaces as an HTTP 500. The endpoints should reject it with their standard
|
|
``{"ok": False, "error": ...}`` response instead.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
def _route_endpoint(router, path: str, method: str):
|
|
method = method.upper()
|
|
for route in router.routes:
|
|
if route.path == path and method in getattr(route, "methods", set()):
|
|
return route.endpoint
|
|
raise AssertionError(f"route not found: {method} {path}")
|
|
|
|
|
|
def test_coerce_port_accepts_int_and_numeric_string():
|
|
import routes.email_routes as email_routes
|
|
assert email_routes._coerce_port(2525, 993) == (2525, None)
|
|
assert email_routes._coerce_port("465", 993) == (465, None)
|
|
|
|
|
|
def test_coerce_port_blank_uses_default():
|
|
import routes.email_routes as email_routes
|
|
assert email_routes._coerce_port(None, 993) == (993, None)
|
|
assert email_routes._coerce_port("", 465) == (465, None)
|
|
|
|
|
|
def test_coerce_port_rejects_non_numeric():
|
|
import routes.email_routes as email_routes
|
|
port, err = email_routes._coerce_port("imap", 993)
|
|
assert port is None
|
|
assert err and "port" in err.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_account_rejects_non_numeric_port():
|
|
"""A bad port is rejected before any DB work, with the endpoint's error shape."""
|
|
import routes.email_routes as email_routes
|
|
router = email_routes.setup_email_routes()
|
|
create = _route_endpoint(router, "/api/email/accounts", "POST")
|
|
result = await create(
|
|
{
|
|
"name": "Test",
|
|
"imap_host": "mail.example.com",
|
|
"imap_user": "u",
|
|
"imap_password": "p",
|
|
"imap_port": "not-a-number",
|
|
},
|
|
owner="alice",
|
|
)
|
|
assert result["ok"] is False
|
|
assert "port" in result["error"].lower()
|