domain migration

This commit is contained in:
debu-2 2026-10-04 14:40:06 +05:30
parent 192b810eb4
commit c04a6ce6fe
26 changed files with 777 additions and 125 deletions

View file

@ -2,8 +2,16 @@
from unittest.mock import patch
from app.services.dns_verification import verify_company_dns
import pytest
from app.services.dns_verification import (
ownership_record_value,
verify_company_dns,
verify_dmarc,
)
from app.services.domain_policy import assert_company_domain_allowed
from app.services.domain_provisioning import (
account_is_domain_owner,
build_company_dns_records,
build_shared_mx_spf_value,
register_relay_domain,
@ -13,30 +21,34 @@ from app.services.domain_provisioning import (
def test_build_company_dns_records_use_shared_mx_and_spf_include():
records = build_company_dns_records(
"acme.com",
"mail.getall.help",
"mail.gentic.email",
"agmail",
"abc123public",
"_spf.getall.help",
"_spf.gentic.email",
"verify-token-123",
)
purposes = [record["purpose"] for record in records]
assert purposes == ["mx", "spf", "dkim", "dmarc"]
assert purposes == ["ownership", "mx", "spf", "dkim", "dmarc"]
ownership = next(record for record in records if record["purpose"] == "ownership")
mx = next(record for record in records if record["purpose"] == "mx")
spf = next(record for record in records if record["purpose"] == "spf")
dkim = next(record for record in records if record["purpose"] == "dkim")
assert ownership["host"] == "_agmail-verify"
assert ownership["value"] == ownership_record_value("verify-token-123")
assert mx["host"] == "@"
assert mx["value"] == "mail.getall.help"
assert mx["value"] == "mail.gentic.email"
assert mx["priority"] == 10
assert spf["value"] == "v=spf1 include:_spf.getall.help ~all"
assert spf["value"] == "v=spf1 include:_spf.gentic.email ~all"
assert dkim["host"] == "agmail._domainkey"
assert "abc123public" in dkim["value"]
assert not any(record.get("purpose") == "mail_host" for record in records)
def test_build_shared_mx_spf_value():
assert build_shared_mx_spf_value("_spf.getall.help") == (
"v=spf1 include:_spf.getall.help ~all"
assert build_shared_mx_spf_value("_spf.gentic.email") == (
"v=spf1 include:_spf.gentic.email ~all"
)
@ -56,32 +68,48 @@ def test_register_relay_domain_appends_once(tmp_path, monkeypatch):
get_settings.cache_clear()
@patch("app.services.dns_verification._lookup_a")
@patch("app.services.dns_verification._lookup_mx")
def test_assert_company_domain_allowed_blocks_platform_and_google():
with pytest.raises(ValueError, match="platform domain"):
assert_company_domain_allowed("gentic.email", "gentic.email")
with pytest.raises(ValueError, match="cannot be used"):
assert_company_domain_allowed("google.com", "gentic.email")
assert assert_company_domain_allowed("acme.com", "gentic.email") == "acme.com"
@patch("app.services.dns_verification._lookup_txt")
def test_verify_company_dns_all_pass(mock_txt, mock_mx, mock_a):
mock_mx.return_value = [(10, "mail.getall.help")]
mock_a.return_value = ["38.180.106.242"]
def test_verify_dmarc_requires_exact_match(mock_txt):
expected = "v=DMARC1; p=quarantine; rua=mailto:dmarc@acme.com"
mock_txt.return_value = ["v=DMARC1; p=reject; rua=mailto:security@google.com"]
verified, message = verify_dmarc("acme.com", expected)
assert verified is False
assert "exactly" in message.lower()
@patch("app.services.dns_verification._lookup_txt")
@patch("app.services.dns_verification._lookup_mx")
def test_verify_company_dns_all_pass(mock_mx, mock_txt):
mock_mx.return_value = [(10, "mail.gentic.email")]
mock_txt.side_effect = lambda name: {
"acme.com": ['v=spf1 include:_spf.getall.help ~all'],
"_spf.getall.help": ["v=spf1 ip4:38.180.106.242 ~all"],
"_agmail-verify.acme.com": [ownership_record_value("token-abc")],
"acme.com": ['v=spf1 include:_spf.gentic.email ~all'],
"agmail._domainkey.acme.com": ["v=DKIM1; k=rsa; p=abc123"],
"_dmarc.acme.com": ["v=DMARC1; p=quarantine; rua=mailto:dmarc@acme.com"],
}.get(name, [])
checks = verify_company_dns(
domain_name="acme.com",
shared_mail_host="mail.getall.help",
shared_mail_host="mail.gentic.email",
dkim_selector="agmail",
dkim_public_key="abc123",
platform_spf_include="_spf.getall.help",
platform_spf_include="_spf.gentic.email",
verification_token="token-abc",
)
assert all(check["verified"] for check in checks)
assert [check["purpose"] for check in checks] == [
"ownership",
"mx",
"spf",
"platform_spf",
"dkim",
"dmarc",
]

View file

@ -9,18 +9,18 @@ from app.services.domain_provisioning import (
def test_namecheap_host_strips_zone_suffix():
assert namecheap_host("mail.getall.help", "getall.help") == "mail"
assert namecheap_host("@", "getall.help") == "@"
assert namecheap_host("mail.gentic.email", "gentic.email") == "mail"
assert namecheap_host("@", "gentic.email") == "@"
assert (
namecheap_host("agmail._domainkey.getall.help", "getall.help")
namecheap_host("agmail._domainkey.gentic.email", "gentic.email")
== "agmail._domainkey"
)
def test_build_dns_records_uses_namecheap_hosts_and_ip():
records = build_dns_records(
"getall.help",
"mail.getall.help",
"gentic.email",
"mail.gentic.email",
"agmail",
"abc123",
mail_server_ip="203.0.113.10",
@ -30,7 +30,7 @@ def test_build_dns_records_uses_namecheap_hosts_and_ip():
spf = next(record for record in records if record["purpose"] == "spf")
assert mx["host"] == "@"
assert mx["value"] == "mail.getall.help"
assert mx["value"] == "mail.gentic.email"
assert mx["priority"] == 10
assert a_record["host"] == "mail"
assert a_record["value"] == "203.0.113.10"
@ -44,11 +44,11 @@ def test_build_spf_value_supports_ipv6():
def test_deployment_sections_split_inbound_and_outbound():
sections = build_deployment_dns_records(
domain_name="getall.help",
domain_name="gentic.email",
mail_server_ip="203.0.113.10",
dkim_selector="agmail",
dkim_public_key="test-public-key",
app_public_host="email.getall.help",
app_public_host="email.gentic.email",
)
inbound_purposes = [record["purpose"] for record in sections["inbound"]]
@ -67,7 +67,7 @@ def test_deployment_sections_split_inbound_and_outbound():
dmarc = next(
record for record in sections["outbound"] if record["purpose"] == "dmarc"
)
assert dmarc["value"] == "v=DMARC1; p=quarantine; rua=mailto:dmarc@getall.help"
assert dmarc["value"] == "v=DMARC1; p=quarantine; rua=mailto:dmarc@gentic.email"
dkim = next(
record for record in sections["outbound"] if record["purpose"] == "dkim"

View file

@ -24,7 +24,7 @@ def test_summary_uses_account_mailbox_read_state():
"_id": message_id,
"direction": "inbound",
"sender": {"name": "Sender", "address": "sender@example.com"},
"to": [{"name": "user", "address": "user@getall.help"}],
"to": [{"name": "user", "address": "user@gentic.email"}],
"subject": "Hello",
"snippet": "A short preview",
"status": "received",

View file

@ -9,7 +9,7 @@ from app.services.raw_mime_storage import StoredMime
RAW = (
b"From: Sender <sender@example.com>\r\n"
b"To: user@getall.help\r\n"
b"To: user@gentic.email\r\n"
b"Subject: Hello\r\n\r\n"
b"Retry safe body\r\n"
)
@ -57,9 +57,9 @@ class FakeSession:
def envelope(raw=RAW):
return SimpleNamespace(
original_content=raw,
rcpt_tos=["user@getall.help"],
rcpt_tos=["user@gentic.email"],
mail_from="sender@example.com",
account_ids={"user@getall.help": "account-1"},
account_ids={"user@gentic.email": "account-1"},
)
@ -72,7 +72,7 @@ async def test_rcpt_rejects_unknown_account(monkeypatch):
None,
None,
target,
"missing@getall.help",
"missing@gentic.email",
[],
)
@ -95,8 +95,8 @@ async def test_rcpt_accepts_account_and_tracks_owner(monkeypatch):
)
assert response.startswith("250 2.1.5")
assert target.rcpt_tos == ["user@getall.help"]
assert target.account_ids == {"user@getall.help": "account-1"}
assert target.rcpt_tos == ["user@gentic.email"]
assert target.account_ids == {"user@gentic.email": "account-1"}
@pytest.mark.asyncio

View file

@ -4,7 +4,7 @@ from app.services.mime_parser import parse_mime
def test_parse_mime_extracts_fallback_sender_bodies_and_attachments():
raw = (
b"From: sender@example.com\r\n"
b"To: User <user@getall.help>\r\n"
b"To: User <user@gentic.email>\r\n"
b"Subject: Production test\r\n"
b"Message-ID: <one@example.com>\r\n"
b"MIME-Version: 1.0\r\n"