Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020
This commit is contained in:
commit
cb5be898ea
663 files changed
+82674
No files matched your search
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Prove one Fleet Ops demo-token MCP call, then prove its revocation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from scripts.revoke_demo_token import revoke
|
||||
from services.runtime.demo_token import load_demo_token_signing_key, mint_demo_token
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class HttpResult:
|
||||
status: int
|
||||
content_type: str
|
||||
body: bytes
|
||||
|
||||
|
||||
def post_tool_call(endpoint: str, token: str, *, timeout_seconds: float) -> HttpResult:
|
||||
request = urllib.request.Request( # noqa: S310 - operator supplies an explicit HTTP(S) MCP endpoint
|
||||
endpoint,
|
||||
data=json.dumps(
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "demo-token-flow-verification",
|
||||
"method": "tools/call",
|
||||
"params": {"name": "mobilityops.operations.summary", "arguments": {}},
|
||||
},
|
||||
separators=(",", ":"),
|
||||
).encode("utf-8"),
|
||||
headers={
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"MCP-Protocol-Version": "2025-11-25",
|
||||
},
|
||||
method="POST",
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(request, timeout=timeout_seconds) as response: # noqa: S310
|
||||
return HttpResult(response.status, response.headers.get_content_type(), response.read())
|
||||
except urllib.error.HTTPError as error:
|
||||
try:
|
||||
body = error.read()
|
||||
except (OSError, ConnectionError):
|
||||
# The status/header proof remains authoritative when the peer closes
|
||||
# the optional error-body stream immediately after sending its 401.
|
||||
body = b""
|
||||
return HttpResult(error.code, error.headers.get_content_type(), body)
|
||||
|
||||
|
||||
def verify_flow(
|
||||
endpoint: str,
|
||||
key_file: Path,
|
||||
revocations_file: Path,
|
||||
*,
|
||||
timeout_seconds: float = 15.0,
|
||||
) -> tuple[HttpResult, HttpResult]:
|
||||
"""Run a bounded live proof and revoke its generated bearer in all cases."""
|
||||
|
||||
key = load_demo_token_signing_key(key_file)
|
||||
token, jti = mint_demo_token(key, ttl_hours=1)
|
||||
try:
|
||||
valid = post_tool_call(endpoint, token, timeout_seconds=timeout_seconds)
|
||||
if valid.status != 200:
|
||||
raise RuntimeError(f"valid demo-token call returned HTTP {valid.status}")
|
||||
if valid.content_type != "application/json":
|
||||
raise RuntimeError("valid demo-token call did not return application/json")
|
||||
try:
|
||||
document: Any = json.loads(valid.body)
|
||||
except (UnicodeDecodeError, ValueError) as exc:
|
||||
raise RuntimeError("valid demo-token call returned invalid JSON") from exc
|
||||
if not isinstance(document, dict):
|
||||
raise RuntimeError("valid demo-token call returned a non-object JSON payload")
|
||||
finally:
|
||||
revoke(revocations_file, jti)
|
||||
|
||||
revoked = post_tool_call(endpoint, token, timeout_seconds=timeout_seconds)
|
||||
if revoked.status != 401:
|
||||
raise RuntimeError(f"revoked demo-token call returned HTTP {revoked.status}, expected 401")
|
||||
return valid, revoked
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--endpoint", required=True)
|
||||
parser.add_argument("--key-file", type=Path, required=True)
|
||||
parser.add_argument("--revocations-file", type=Path, required=True)
|
||||
parser.add_argument("--timeout-seconds", type=float, default=15.0)
|
||||
args = parser.parse_args()
|
||||
if not 1 <= args.timeout_seconds <= 30:
|
||||
raise ValueError("timeout-seconds must be between 1 and 30")
|
||||
valid, revoked = verify_flow(
|
||||
args.endpoint,
|
||||
args.key_file,
|
||||
args.revocations_file,
|
||||
timeout_seconds=args.timeout_seconds,
|
||||
)
|
||||
print(f"valid_call_http={valid.status}")
|
||||
print(f"valid_call_content_type={valid.content_type}")
|
||||
print(f"valid_call_bytes={len(valid.body)}")
|
||||
print(f"revoked_call_http={revoked.status}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user