mirror of
https://github.com/mcloh/Enterprise-MCP-Service-Bus.git
synced 2026-11-05 22:14:11 +00:00
73 lines
2.2 KiB
Python
73 lines
2.2 KiB
Python
"""Header/body consistency check (EP-05-T08, README.md §22, SEP-2243)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
from emcp_bus.gateway.canonical_request import find_header_body_mismatch
|
|
|
|
|
|
def _body(method: str, params: dict[str, object] | None = None) -> bytes:
|
|
return json.dumps(
|
|
{"jsonrpc": "2.0", "id": 1, "method": method, "params": params or {}}
|
|
).encode()
|
|
|
|
|
|
def test_no_headers_present_is_never_a_mismatch() -> None:
|
|
assert (
|
|
find_header_body_mismatch(_body("tools/call"), method_header=None, name_header=None) is None
|
|
)
|
|
|
|
|
|
def test_matching_method_header_is_not_a_mismatch() -> None:
|
|
body = _body("tools/list")
|
|
|
|
assert find_header_body_mismatch(body, method_header="tools/list", name_header=None) is None
|
|
|
|
|
|
def test_mismatched_method_header_is_rejected() -> None:
|
|
body = _body("tools/list")
|
|
|
|
reason = find_header_body_mismatch(body, method_header="tools/call", name_header=None)
|
|
|
|
assert reason is not None
|
|
assert "mcp-method" in reason
|
|
|
|
|
|
def test_matching_name_header_for_tools_call_is_not_a_mismatch() -> None:
|
|
body = _body("tools/call", {"name": "sales.customer.get", "arguments": {}})
|
|
|
|
reason = find_header_body_mismatch(
|
|
body, method_header="tools/call", name_header="sales.customer.get"
|
|
)
|
|
|
|
assert reason is None
|
|
|
|
|
|
def test_mismatched_name_header_for_tools_call_is_rejected() -> None:
|
|
"""The concrete attack this closes: a header claiming one tool while the
|
|
body actually invokes another -- whichever a naive reader trusted, the
|
|
request must instead be rejected outright (README.md §22)."""
|
|
body = _body("tools/call", {"name": "finance.payment.execute", "arguments": {}})
|
|
|
|
reason = find_header_body_mismatch(
|
|
body, method_header="tools/call", name_header="sales.customer.get"
|
|
)
|
|
|
|
assert reason is not None
|
|
assert "mcp-name" in reason
|
|
|
|
|
|
def test_name_header_is_irrelevant_for_a_non_name_bearing_method() -> None:
|
|
body = _body("tools/list")
|
|
|
|
reason = find_header_body_mismatch(body, method_header="tools/list", name_header="anything")
|
|
|
|
assert reason is None
|
|
|
|
|
|
def test_unparseable_body_is_left_to_the_app_itself() -> None:
|
|
reason = find_header_body_mismatch(b"not json", method_header="tools/list", name_header=None)
|
|
|
|
assert reason is None
|