test_security.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import asyncio
  2. import httpx
  3. from fastapi import FastAPI
  4. from core_shared.config import ServiceSettings
  5. from core_shared.security import (
  6. add_internal_service_auth,
  7. build_internal_service_headers,
  8. mask_sensitive_mapping,
  9. )
  10. def test_mask_sensitive_mapping_masks_nested_secrets() -> None:
  11. payload = {
  12. "api_key": "agp_super_secret_value",
  13. "nested": {"authorization": "Bearer token-value"},
  14. "safe": "visible",
  15. }
  16. masked = mask_sensitive_mapping(payload)
  17. assert masked["api_key"] != payload["api_key"]
  18. assert masked["nested"]["authorization"] != payload["nested"]["authorization"]
  19. assert masked["safe"] == "visible"
  20. def test_internal_service_auth_middleware_requires_token() -> None:
  21. asyncio.run(_run_internal_service_auth_smoke())
  22. async def _run_internal_service_auth_smoke() -> None:
  23. settings = ServiceSettings(
  24. service_name="test-service",
  25. internal_service_auth_required=True,
  26. internal_service_token="secret-token",
  27. )
  28. app = FastAPI()
  29. add_internal_service_auth(app, settings)
  30. @app.get("/private")
  31. async def private() -> dict[str, str]:
  32. return {"status": "ok"}
  33. transport = httpx.ASGITransport(app=app)
  34. async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client:
  35. denied_response = await client.get("/private")
  36. allowed_response = await client.get(
  37. "/private",
  38. headers=build_internal_service_headers(settings, source_service="caller"),
  39. )
  40. health_response = await client.get("/private/health")
  41. assert denied_response.status_code == 401
  42. assert allowed_response.status_code == 200
  43. assert health_response.status_code == 404