53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
import base64
|
|
import os
|
|
|
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
from fastapi.testclient import TestClient
|
|
|
|
os.environ["JWT_SECRET"] = "test-secret-must-be-32-characters!"
|
|
os.environ["API_PAYLOAD_ENCRYPT"] = "false"
|
|
os.environ["API_PAYLOAD_AES_KEY"] = base64.b64encode(b"0123456789abcdef0123456789abcdef").decode()
|
|
|
|
from app.core.config import get_settings
|
|
from app.core.security import create_access_token
|
|
from app.main import create_app
|
|
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def test_site_health_is_public():
|
|
client = TestClient(create_app())
|
|
response = client.get("/api/site/health")
|
|
assert response.status_code == 200
|
|
assert response.json()["scope"] == "site"
|
|
|
|
|
|
def test_admin_requires_staff_token():
|
|
client = TestClient(create_app())
|
|
assert client.get("/api/admin/health").status_code == 401
|
|
member = create_access_token("member-1", "member")
|
|
rejected = client.get("/api/admin/health", headers={"Authorization": f"Bearer {member}"})
|
|
assert rejected.status_code == 403
|
|
staff = create_access_token("staff-1", "staff")
|
|
accepted = client.get("/api/admin/health", headers={"Authorization": f"Bearer {staff}"})
|
|
assert accepted.status_code == 200
|
|
assert accepted.json()["subject"] == "staff-1"
|
|
|
|
|
|
def test_payload_encryption_roundtrip(monkeypatch):
|
|
monkeypatch.setenv("API_PAYLOAD_ENCRYPT", "true")
|
|
get_settings.cache_clear()
|
|
client = TestClient(create_app())
|
|
key = base64.b64decode(os.environ["API_PAYLOAD_AES_KEY"])
|
|
nonce = b"123456789012"
|
|
plain = b'{"ping":true}'
|
|
token = base64.b64encode(nonce + AESGCM(key).encrypt(nonce, plain, None)).decode()
|
|
response = client.post("/api/site/health", json={"data": token})
|
|
assert response.status_code == 405
|
|
body = response.json()
|
|
assert "data" in body
|
|
raw = base64.b64decode(body["data"])
|
|
decoded = AESGCM(key).decrypt(raw[:12], raw[12:], None)
|
|
assert b"Method Not Allowed" in decoded or "detail" in decoded.decode()
|
|
get_settings.cache_clear()
|