Commit 7e88cbbe authored by George Papathanail's avatar George Papathanail
Browse files

fix: require a UUID partnerOpId to match FM's partner ids

parent 441def16
Loading
Loading
Loading
Loading
Loading
+4 −2
Changes for src/open_exposure_gateway/api/gsma/federation_manager/v1_4_0/schemas.py: 4 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ from __future__ import annotations
from datetime import datetime
from enum import StrEnum
from typing import Annotated, Optional
from uuid import UUID

from pydantic import BaseModel, Field, StringConstraints, model_validator

@@ -35,10 +36,11 @@ FederationIdentifier = Annotated[str, StringConstraints(pattern=_ID_PATTERN)]

ZoneIdentifier = Annotated[str, StringConstraints(pattern=_ID_PATTERN)]

PartnerOpId = Annotated[str, StringConstraints(pattern=_ID_PATTERN)]
PartnerOpId = UUID
"""Our own registered id for the partner operator platform (not part of GSMA -- this
is the platform-namespace path param that says which partner an EWBI call is for,
since the GSMA body itself never names the callee)."""
since the GSMA body itself never names the callee). FM assigns it as a UUID when the
partner is registered, and its ``/internal`` routes accept nothing else."""

CountryCode = Annotated[str, StringConstraints(pattern=r"^[A-Z]{2}$")]
"""ISO 3166-1 Alpha-2 country code of the partner operator."""
+12 −1
Changes for tests/unit/test_federation_manager_endpoints.py: 12 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ from open_exposure_gateway.api.gsma.federation_manager.v1_4_0.problems import BA
from open_exposure_gateway.dependencies import get_fm_client
from open_exposure_gateway.main import app

_PARTNER = "partner-op-1"
_PARTNER = "5f0c2a8e-3b1d-4c6e-9a7f-1d2e3f4a5b6c"
_CTX = "fed-ctx-1"
_ZONE = "zone-a"
_FEDERATIONS = f"/partners/{_PARTNER}/federations"
@@ -581,6 +581,17 @@ def test_invalid_path_param_returns_problem_details_400(
    assert fake_fm_client.calls == []


def test_non_uuid_partner_op_id_is_rejected_before_reaching_fm(
    client: TestClient, fake_fm_client: _FakeFmClient
) -> None:
    """FM registers partners under UUIDs, so a readable slug never reaches it."""
    response = client.get(f"{BASE_PATH}/partners/partner-op-berlin/federations")

    assert response.status_code == 400
    assert [p["param"] for p in response.json()["invalidParams"]] == ["partnerOpId"]
    assert fake_fm_client.calls == []


def test_invalid_x_correlator_returns_problem_details_400(
    client: TestClient, fake_fm_client: _FakeFmClient
) -> None: