Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 8m30s
Preserve the four unpublished T02 checkpoints with identical implementation and test contents. Represent Kubernetes resource UIDs as explicit kind/resource_uid metadata so they are not mistaken for credential values. Standard staged-blob scanner clean; full repository gate 764 passed. T02 remains open for received authentication and native return acceptance. Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a198ed-70cc-7362-a569-d5dbef39b86a
383 lines
14 KiB
Python
383 lines
14 KiB
Python
"""Selected read-only IMAP and temporary-policy lifecycle, with no network."""
|
|
|
|
import copy
|
|
import hashlib
|
|
import importlib
|
|
import json
|
|
import os
|
|
import sqlite3
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
SCRIPTS = Path(__file__).resolve().parents[1] / "scripts"
|
|
sys.path.insert(0, str(SCRIPTS))
|
|
check = importlib.import_module("selected_mailbox_check")
|
|
probe = importlib.import_module("platform_mail_probe")
|
|
|
|
REFERENCE = "<fixture-message@example.test>"
|
|
RAW = (
|
|
"From: operator@example.test\r\nTo: platform@example.test\r\n"
|
|
"In-Reply-To: " + REFERENCE + "\r\n\r\nSelected fixture reply.\r\n"
|
|
).encode()
|
|
|
|
|
|
class Mailbox:
|
|
def __init__(self, *args, **kwargs):
|
|
assert args == ("imap.example.test", 993)
|
|
assert kwargs["ssl_context"].check_hostname
|
|
self.calls = []
|
|
self.count = b"1"
|
|
self.raw = RAW
|
|
|
|
def login(self, username, password):
|
|
assert (username, password) == ("platform@example.test", "fixture-password")
|
|
self.calls.append("login")
|
|
return "OK", []
|
|
|
|
def select(self, name, *, readonly):
|
|
assert name == "INBOX" and readonly is True
|
|
self.calls.append("readonly")
|
|
return "OK", []
|
|
|
|
def uid(self, action, *args):
|
|
self.calls.append((action, args))
|
|
if action == "search":
|
|
assert args == (None, "TEXT", '"' + REFERENCE + '"')
|
|
return "OK", [self.count]
|
|
assert action == "fetch" and args[0] == b"1"
|
|
if args[1] == "(RFC822.SIZE)":
|
|
return "OK", [b"1 (UID 1 RFC822.SIZE " + str(len(self.raw)).encode() + b")"]
|
|
assert args[1] == "(BODY.PEEK[])"
|
|
return "OK", [(b"1 (BODY[])", self.raw), b")"]
|
|
|
|
def logout(self):
|
|
self.calls.append("logout")
|
|
|
|
|
|
@pytest.fixture
|
|
def mailbox(monkeypatch):
|
|
monkeypatch.setattr(check, "HOST", "imap.example.test")
|
|
return Mailbox("imap.example.test", 993, ssl_context=__import__("ssl").create_default_context())
|
|
|
|
|
|
def retrieve(mailbox):
|
|
return check.retrieve(
|
|
REFERENCE,
|
|
"person@example.test",
|
|
"platform@example.test",
|
|
"fixture-password",
|
|
client=lambda *a, **k: mailbox,
|
|
)
|
|
|
|
|
|
def test_only_exact_reference_readonly_and_peek_are_used(mailbox):
|
|
result = retrieve(mailbox)
|
|
assert len(result) == 1 and result[0]["kind"] == "reply"
|
|
assert mailbox.calls[0:2] == ["login", "readonly"]
|
|
assert mailbox.calls[-1] == "logout"
|
|
|
|
|
|
def test_unrelated_matching_text_is_not_retained(mailbox):
|
|
mailbox.raw = b"From: fixture@example.test\r\n\r\nMention " + REFERENCE.encode()
|
|
assert retrieve(mailbox) == []
|
|
|
|
|
|
def test_more_than_five_matches_refuses_before_fetch_and_logs_out(mailbox):
|
|
mailbox.count = b"1 2 3 4 5 6"
|
|
with pytest.raises(check.operation.Refused):
|
|
retrieve(mailbox)
|
|
assert not any(isinstance(c, tuple) and c[0] == "fetch" for c in mailbox.calls)
|
|
assert mailbox.calls[-1] == "logout"
|
|
|
|
|
|
def test_oversized_message_refuses_before_body_fetch(mailbox, monkeypatch):
|
|
monkeypatch.setattr(check, "MAX_BYTES", 10)
|
|
with pytest.raises(check.operation.Refused):
|
|
retrieve(mailbox)
|
|
assert not any(isinstance(c, tuple) and "(BODY.PEEK[])" in c[1] for c in mailbox.calls)
|
|
|
|
|
|
def test_imap_search_injection_refused_before_connect():
|
|
with pytest.raises(check.operation.Refused):
|
|
check.retrieve(
|
|
'<bad" ALL>',
|
|
"fixture@example.test",
|
|
"fixture",
|
|
"fixture",
|
|
client=lambda *a, **k: pytest.fail("connected"),
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("addresses", [[], ["127.0.0.1"], ["10.1.2.3"], ["::1"]])
|
|
def test_egress_rejects_private_and_non_ipv4_destinations(addresses):
|
|
with pytest.raises(check.operation.Refused):
|
|
check.policy_for("fixture", addresses)
|
|
|
|
|
|
class Cluster:
|
|
def __init__(self, monkeypatch):
|
|
self.context = {
|
|
"cluster_uid": "cluster",
|
|
"namespace_uid": "namespace",
|
|
"deployment_uid": "deployment",
|
|
"image": "fixture@sha256:abc",
|
|
"pod_name": "fixture",
|
|
"generation": 79,
|
|
}
|
|
monkeypatch.setattr(check.native, "identity", lambda command: self.context)
|
|
self.obj = None
|
|
self.calls = []
|
|
self.fail_exec = False
|
|
self.fail_cleanup = False
|
|
|
|
def __call__(self, args, payload=None):
|
|
self.calls.append(args)
|
|
if args[0] == "get":
|
|
return {"items": [self.obj] if self.obj else []}
|
|
if args[0] == "create":
|
|
self.obj = json.loads(payload)
|
|
self.obj["metadata"]["uid"] = "owned-policy-uid"
|
|
return copy.deepcopy(self.obj)
|
|
if args[0] == "delete":
|
|
assert json.loads(payload)["preconditions"] == {"uid": "owned-policy-uid"}
|
|
if self.fail_cleanup:
|
|
raise OSError("modeled deletion failure")
|
|
self.obj = None
|
|
return {"status": "Success"}
|
|
assert args[0] == "exec"
|
|
if self.fail_exec:
|
|
raise OSError("modeled IMAP failure")
|
|
return {"messages": []}
|
|
|
|
def request(self, action="fetch"):
|
|
return {
|
|
"action": action,
|
|
"packet": {
|
|
"context": copy.deepcopy(self.context),
|
|
"reference": REFERENCE,
|
|
"binding": {"caller_policy_sha256": "fixture-policy"},
|
|
"policy": check.policy_for("email-connect-selected-0123456789abcdef", ["1.1.1.1"]),
|
|
},
|
|
"sources": {n: (SCRIPTS / n).read_text() for n in check.FILES},
|
|
}
|
|
|
|
|
|
def test_native_attempt_cleans_only_its_owned_policy(monkeypatch):
|
|
cluster = Cluster(monkeypatch)
|
|
result = check.run_node(cluster.request(), cluster)
|
|
assert result["temporary_policy_absent"] and cluster.obj is None
|
|
assert [c[0] for c in cluster.calls] == ["get", "create", "exec", "get", "delete", "get"]
|
|
|
|
|
|
def test_imap_failure_still_removes_temporary_egress(monkeypatch):
|
|
cluster = Cluster(monkeypatch)
|
|
cluster.fail_exec = True
|
|
with pytest.raises(OSError):
|
|
check.run_node(cluster.request(), cluster)
|
|
assert cluster.obj is None
|
|
|
|
|
|
def test_lost_cleanup_refuses_then_explicit_cleanup_removes_same_uid(monkeypatch):
|
|
cluster = Cluster(monkeypatch)
|
|
cluster.fail_cleanup = True
|
|
with pytest.raises(OSError):
|
|
check.run_node(cluster.request(), cluster)
|
|
assert cluster.obj is not None
|
|
cluster.fail_cleanup = False
|
|
assert check.run_node(cluster.request("cleanup"), cluster)["temporary_policy_absent"]
|
|
assert cluster.obj is None
|
|
|
|
|
|
def test_changed_receiver_or_prior_policy_refuses_without_mailbox_access(monkeypatch):
|
|
cluster = Cluster(monkeypatch)
|
|
request = cluster.request()
|
|
request["packet"]["context"]["generation"] = 78
|
|
with pytest.raises(check.operation.Refused):
|
|
check.run_node(request, cluster)
|
|
assert cluster.calls == []
|
|
cluster.obj = copy.deepcopy(cluster.request()["packet"]["policy"])
|
|
with pytest.raises(check.operation.Refused):
|
|
check.run_node(cluster.request(), cluster)
|
|
assert all(c[0] == "get" for c in cluster.calls)
|
|
|
|
|
|
@pytest.fixture
|
|
def probe_packet(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(probe, "ENDPOINT", "https://users.example.test/api/v1/public/registrations")
|
|
monkeypatch.setattr(
|
|
probe,
|
|
"TESTS",
|
|
{"fixture-one": "person@example.test", "fixture-two": "fixture@example.invalid"},
|
|
)
|
|
tmp_path.chmod(0o700)
|
|
return probe.prepare(), tmp_path / "probe.json"
|
|
|
|
|
|
def test_probe_exact_bodies_idempotency_and_no_replay(probe_packet):
|
|
packet, path = probe_packet
|
|
calls = []
|
|
|
|
class Response:
|
|
status = 202
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *args):
|
|
pass
|
|
|
|
def read(self, size):
|
|
return b'{"status":"verification_requested"}'
|
|
|
|
def open_request(request, **kwargs):
|
|
calls.append(request)
|
|
return Response()
|
|
|
|
result = probe.send(packet, path, probe.operation.digest(packet), opener=open_request)
|
|
assert len(calls) == 2 and not result["identity_provisioned"]
|
|
assert len({c.headers["Idempotency-key"] for c in calls}) == 2
|
|
with pytest.raises(FileExistsError):
|
|
probe.send(packet, path, probe.operation.digest(packet), opener=open_request)
|
|
assert len(calls) == 2
|
|
|
|
|
|
def test_uncertain_probe_stops_before_second_and_keeps_intent(probe_packet):
|
|
packet, path = probe_packet
|
|
calls = []
|
|
|
|
def failure(*args, **kwargs):
|
|
calls.append(1)
|
|
raise TimeoutError("modeled lost response")
|
|
|
|
result = probe.send(packet, path, probe.operation.digest(packet), opener=failure)
|
|
assert len(calls) == 1 and path.with_suffix(".intent.json").exists()
|
|
assert result["requests"][0]["status"] == "unconfirmed_inspect_before_retry"
|
|
|
|
|
|
def test_actual_pod_program_loads_capsule_and_binds_accepted_sqlite_send(tmp_path):
|
|
package = tmp_path / "email_connect"
|
|
package.mkdir()
|
|
(package / "__init__.py").write_text("")
|
|
hashes = {}
|
|
for name in ("transactional", "callers"):
|
|
source = b"# Fixture installed module.\n"
|
|
(package / (name + ".py")).write_bytes(source)
|
|
hashes[name] = hashlib.sha256(source).hexdigest()
|
|
database = tmp_path / "fixture.db"
|
|
policy_path = tmp_path / "callers.json"
|
|
document = {
|
|
"schema_version": 1,
|
|
"callers": [
|
|
{
|
|
"caller_id": "user-engine",
|
|
"bindings": [["tenant:coulomb", "coulomb-social"]],
|
|
"adopt_legacy_verifications": True,
|
|
}
|
|
],
|
|
}
|
|
policy_path.write_text(json.dumps(document))
|
|
with sqlite3.connect(database) as db:
|
|
db.executescript(
|
|
"CREATE TABLE verifications(request_id,username,email,caller_id,tenant,client_id);"
|
|
"CREATE TABLE verification_attempts(request_id,provider_ref,state);"
|
|
)
|
|
db.execute(
|
|
"INSERT INTO verifications VALUES(?,?,?,?,?,?)",
|
|
(
|
|
"request",
|
|
"fixture-user",
|
|
"person@example.test",
|
|
"user-engine",
|
|
"tenant:coulomb",
|
|
"coulomb-social",
|
|
),
|
|
)
|
|
db.execute(
|
|
"INSERT INTO verification_attempts VALUES(?,?,?)", ("request", REFERENCE, "accepted")
|
|
)
|
|
sources = {name: (SCRIPTS / name).read_text() for name in check.FILES}
|
|
sources["selected_mailbox_check.py"] = sources["selected_mailbox_check.py"].replace(
|
|
'HOST = "imap.ionos.de"', 'HOST = "imap.example.test"'
|
|
)
|
|
request = {
|
|
"action": "fetch",
|
|
"reference": REFERENCE,
|
|
"sources": sources,
|
|
"tests": {"fixture-user": "person@example.test"},
|
|
**hashes,
|
|
}
|
|
# Substitute only fixture identity/path/installed-package and IMAP transport.
|
|
# The SQL binding, reviewed capsule loader and retrieval implementation run.
|
|
program = check.POD.replace("os.getuid()==10001", "os.getuid()==" + str(os.getuid()))
|
|
program = program.replace("/data/email-connect.db", str(database)).replace(
|
|
"platform@coulomb.social", "platform@example.test"
|
|
)
|
|
program = program.replace("/etc/email-connect-callers/callers.json", str(policy_path))
|
|
prefix = "import sys,types\nsys.path.insert(0," + repr(str(tmp_path)) + ")\n"
|
|
prefix += (
|
|
"def no_network(event,args):\n"
|
|
" if event in {'socket.connect','socket.getaddrinfo','socket.bind'}:\n"
|
|
" raise RuntimeError('fixture network forbidden')\n"
|
|
"sys.addaudithook(no_network)\n"
|
|
)
|
|
prefix += "class Fake:\n"
|
|
prefix += " def __init__(self,host,port,**kw):assert (host,port)==('imap.example.test',993)\n"
|
|
prefix += (
|
|
" def login(self,user,password):\n"
|
|
" assert (user,password)==('platform@example.test','fixture-password')\n"
|
|
" return 'OK',[]\n"
|
|
)
|
|
prefix += (
|
|
" def select(self,box,readonly=False):\n"
|
|
" assert box=='INBOX' and readonly\n"
|
|
" return 'OK',[]\n"
|
|
)
|
|
prefix += " def uid(self,action,*args):\n"
|
|
prefix += " if action=='search':return 'OK',[b'1']\n"
|
|
prefix += (
|
|
" if args[1]=='(RFC822.SIZE)':return 'OK',[b'1 (RFC822.SIZE " + str(len(RAW)) + ")']\n"
|
|
)
|
|
prefix += (
|
|
" assert args[1]=='(BODY.PEEK[])'\n return 'OK',[(b'BODY[]'," + repr(RAW) + "),b')']\n"
|
|
)
|
|
prefix += " def logout(self):pass\n"
|
|
prefix += "imap=types.ModuleType('imaplib');imap.IMAP4_SSL=Fake;sys.modules['imaplib']=imap\n"
|
|
environment = {
|
|
**os.environ,
|
|
"EMAIL_CONNECT_DATABASE_PATH": str(database),
|
|
"EMAIL_CONNECT_SMTP_USERNAME": "platform@example.test",
|
|
"EMAIL_CONNECT_SENDER": "platform@example.test",
|
|
"EMAIL_CONNECT_SMTP_PASSWORD": "fixture-password",
|
|
"EMAIL_CONNECT_CALLERS_FILE": str(policy_path),
|
|
}
|
|
|
|
def execute():
|
|
return subprocess.run(
|
|
[sys.executable, "-I", "-c", prefix + program],
|
|
input=json.dumps(request).encode(),
|
|
capture_output=True,
|
|
timeout=20,
|
|
check=False,
|
|
env=environment,
|
|
)
|
|
|
|
result = execute()
|
|
assert result.returncode == 0, result.stderr.decode()
|
|
assert json.loads(result.stdout)["messages"][0]["kind"] == "reply"
|
|
with sqlite3.connect(database) as db:
|
|
db.execute("UPDATE verifications SET caller_id=''")
|
|
assert execute().returncode == 0 # Explicit policy adoption is required.
|
|
document["callers"][0]["adopt_legacy_verifications"] = False
|
|
policy_path.write_text(json.dumps(document))
|
|
assert execute().returncode != 0
|
|
document["callers"][0]["adopt_legacy_verifications"] = True
|
|
policy_path.write_text(json.dumps(document))
|
|
request["policy_sha256"] = "changed-policy"
|
|
assert execute().returncode != 0
|
|
request.pop("policy_sha256")
|
|
with sqlite3.connect(database) as db:
|
|
db.execute("UPDATE verification_attempts SET state='in_flight'")
|
|
assert execute().returncode != 0
|