test_attachment_proxy.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. """Admin JWT attachment file proxy."""
  2. import pytest
  3. from app.core import storage
  4. from app.core.config import get_settings
  5. PNG = b"\x89PNG\r\n\x1a\n" + b"\x00" * 8
  6. @pytest.fixture
  7. def local_storage_env(tmp_path, monkeypatch):
  8. monkeypatch.setenv("STORAGE_TYPE", "local")
  9. monkeypatch.setenv("LOCAL_STORAGE_DIR", str(tmp_path))
  10. get_settings.cache_clear()
  11. yield tmp_path
  12. get_settings.cache_clear()
  13. def _token(client):
  14. r = client.post("/api/web/auth/login", json={"username": "admin", "password": "Admin@123"})
  15. return r.json()["data"]["token"]
  16. def test_attachment_proxy_requires_auth(client, local_storage_env):
  17. r = client.get("/api/web/admin/attachment/file", params={"url": "/uploads/feedback/x.png"})
  18. assert r.status_code == 401
  19. def test_attachment_proxy_streams_file(client, local_storage_env):
  20. stored = storage.upload_file(PNG, "a.png", "feedback")
  21. token = _token(client)
  22. r = client.get(
  23. "/api/web/admin/attachment/file",
  24. params={"url": stored["url"]},
  25. headers={"Authorization": f"Bearer {token}"},
  26. )
  27. assert r.status_code == 200
  28. assert r.headers.get("x-content-type-options", "").lower() == "nosniff"
  29. assert "image" in (r.headers.get("content-type") or "")
  30. assert r.content.startswith(b"\x89PNG")
  31. def test_attachment_proxy_rejects_foreign_url(client, local_storage_env):
  32. token = _token(client)
  33. r = client.get(
  34. "/api/web/admin/attachment/file",
  35. params={"url": "https://evil.example/a.png"},
  36. headers={"Authorization": f"Bearer {token}"},
  37. )
  38. assert r.status_code == 400