130 lines
6.2 KiB
Python
130 lines
6.2 KiB
Python
"""Exercise credential separation and secret-safe validation through real middleware."""
|
|
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import text
|
|
|
|
from modelforge_api.api.authorization import AccessBoundary, access_boundary_for_request
|
|
from modelforge_api.db import get_session
|
|
from modelforge_api.domain.serving import ServiceClientCreate
|
|
from modelforge_api.main import app
|
|
from tests.test_operator_authorization import (
|
|
ADMIN,
|
|
ALLOWED_ORIGIN,
|
|
MachineBoundaryHarness,
|
|
machine_boundary_harness,
|
|
)
|
|
from tests.test_selected_comparison_postgres import _valid_selection
|
|
|
|
__all__ = ["machine_boundary_harness"]
|
|
PREFIX = "/api/v1/selected-model-comparisons"
|
|
|
|
|
|
@pytest.mark.parametrize("outcome", ["failed", "cancelled"])
|
|
def test_authenticated_operator_and_designated_consumer_journey(
|
|
machine_boundary_harness: MachineBoundaryHarness, outcome: str,
|
|
) -> None:
|
|
serving = machine_boundary_harness.capability_service
|
|
session = serving.session
|
|
session.execute(text("PRAGMA foreign_keys=ON"))
|
|
assert session.scalar(text("PRAGMA foreign_keys")) == 1
|
|
request, _unused_client = _valid_selection(session)
|
|
issued = serving.create_client(ServiceClientCreate(
|
|
name="comparison-http-consumer", allowed_capabilities=["rag.embedding@1"],
|
|
project_key="selected-comparison-fixture", project_binding_id=request.project_binding_id,
|
|
integration_environment="production", purpose="Offline authenticated comparison qualification",
|
|
))
|
|
request = request.model_copy(update={"consumer_client_id": issued.id})
|
|
app.dependency_overrides[get_session] = lambda: session
|
|
operator = {**ADMIN, "Origin": ALLOWED_ORIGIN}
|
|
consumer = {"Authorization": f"Bearer {issued.credential}", "Origin": ALLOWED_ORIGIN}
|
|
client = TestClient(app)
|
|
created = client.post(PREFIX, headers=operator, json=request.model_dump(mode="json"))
|
|
assert created.status_code == 201, created.text
|
|
comparison_id = created.json()["id"]
|
|
path = f"{PREFIX}/{comparison_id}"
|
|
assert created.json()["status"] == "pending"
|
|
assigned = client.get(f"{PREFIX}/assigned", headers=consumer)
|
|
assert assigned.status_code == 200, assigned.text
|
|
assert [item["id"] for item in assigned.json()["items"]] == [comparison_id]
|
|
claimed = client.post(f"{path}/claim", headers=consumer)
|
|
assert claimed.status_code == 200, claimed.text
|
|
assert claimed.headers["Cache-Control"] == "no-store"
|
|
assert claimed.json()["comparison"]["status"] == "running"
|
|
assert len(claimed.json()["cases"]) == 1
|
|
token = claimed.json()["claim_token"]
|
|
progress = client.post(f"{path}/progress", headers=consumer, json={
|
|
"claim_token": token, "current_completed_cases": 1, "candidate_completed_cases": 0,
|
|
})
|
|
assert progress.status_code == 200, progress.text
|
|
assert progress.json()["current_completed_cases"] == 1
|
|
if outcome == "cancelled":
|
|
cancelled = client.post(f"{path}/cancel", headers=operator,
|
|
json={"expected_version": progress.json()["version"]})
|
|
assert cancelled.status_code == 200, cancelled.text
|
|
assert cancelled.json()["status"] == "cancel_requested"
|
|
finished = client.post(f"{path}/finish", headers=consumer, json={
|
|
"claim_token": token, "outcome": outcome,
|
|
"error_code": "FIXTURE_CONSUMER_FAILURE" if outcome == "failed" else None,
|
|
})
|
|
assert finished.status_code == 200, finished.text
|
|
assert finished.json()["status"] == outcome
|
|
assert finished.json()["production_promotion_performed"] is False
|
|
assert finished.json()["finished_at"] is not None
|
|
history = client.get(PREFIX, headers=operator)
|
|
assert history.status_code == 200
|
|
assert history.json()["items"][0]["status"] == outcome
|
|
detail = client.get(path, headers=operator)
|
|
assert detail.status_code == 200
|
|
assert detail.json()["consumer_client_id"] == str(issued.id)
|
|
assert token not in history.text and token not in detail.text
|
|
assert issued.credential not in history.text
|
|
assert client.get(f"{PREFIX}/assigned", headers=consumer).json()["items"] == []
|
|
assert session.execute(text("PRAGMA foreign_key_check")).all() == []
|
|
|
|
|
|
@pytest.mark.parametrize("action", ["claim", "progress", "result", "finish"])
|
|
def test_operator_key_cannot_become_comparison_consumer(
|
|
machine_boundary_harness: MachineBoundaryHarness, action: str,
|
|
) -> None:
|
|
response = TestClient(app).post(f"{PREFIX}/{uuid4()}/{action}", headers={
|
|
**ADMIN, "Origin": ALLOWED_ORIGIN,
|
|
}, json={"claim_token": "private-test-claim-that-must-not-echo"})
|
|
assert response.status_code == 401
|
|
assert "private-test-claim" not in response.text
|
|
|
|
|
|
@pytest.mark.parametrize("action", ["progress", "result", "finish"])
|
|
def test_consumer_validation_does_not_echo_secret_or_extra_values(
|
|
machine_boundary_harness: MachineBoundaryHarness, action: str,
|
|
) -> None:
|
|
canary = "private-claim-and-payload-canary-123456789"
|
|
response = TestClient(app).post(f"{PREFIX}/{uuid4()}/{action}", headers={
|
|
"Authorization": f"Bearer {machine_boundary_harness.capability_credential}",
|
|
"Origin": ALLOWED_ORIGIN,
|
|
}, json={"claim_token": canary, "unexpected": {canary: canary}})
|
|
assert response.status_code == 422
|
|
assert canary not in response.text
|
|
errors = response.json()["error"]["details"]["errors"]
|
|
assert errors and all(set(error) == {"type", "msg"} for error in errors)
|
|
|
|
|
|
@pytest.mark.parametrize("path", [PREFIX, f"{PREFIX}/{uuid4()}/cancel"])
|
|
def test_project_credential_cannot_plan_or_cancel_operator_comparison(
|
|
machine_boundary_harness: MachineBoundaryHarness, path: str,
|
|
) -> None:
|
|
response = TestClient(app).post(path, headers={
|
|
"Authorization": f"Bearer {machine_boundary_harness.capability_credential}",
|
|
"Origin": ALLOWED_ORIGIN,
|
|
}, json={})
|
|
assert response.status_code == 401
|
|
|
|
|
|
def test_only_exact_assigned_read_is_a_consumer_route() -> None:
|
|
assert access_boundary_for_request("GET", f"{PREFIX}/assigned") is AccessBoundary.CAPABILITY_CLIENT
|
|
assert access_boundary_for_request("GET", PREFIX) is AccessBoundary.CONTROL_PLANE
|
|
assert access_boundary_for_request("GET", f"{PREFIX}/{uuid4()}") is AccessBoundary.CONTROL_PLANE
|
|
assert access_boundary_for_request("POST", f"{PREFIX}/{uuid4()}/cancel") is AccessBoundary.CONTROL_PLANE
|