"""Security bootstrap and API key hashing.""" import hashlib import pytest from app.auth.api_key import _legacy_hash_api_key, hash_api_key, verify_api_key_hash from app.security_bootstrap import validate_security_settings from app.config import Settings def test_hash_api_key_uses_hmac(monkeypatch): monkeypatch.setenv("JWT_SECRET", "unit-test-secret") from app.config import get_settings get_settings.cache_clear() raw = "sac_example_key" assert hash_api_key(raw) != _legacy_hash_api_key(raw) assert verify_api_key_hash(raw, hash_api_key(raw)) get_settings.cache_clear() def test_verify_api_key_hash_accepts_legacy_sha256(monkeypatch): monkeypatch.setenv("JWT_SECRET", "unit-test-secret") from app.config import get_settings get_settings.cache_clear() raw = "sac_legacy_key" legacy = hashlib.sha256(raw.encode("utf-8")).hexdigest() assert verify_api_key_hash(raw, legacy) get_settings.cache_clear() def test_validate_security_settings_rejects_weak_jwt(): settings = Settings( jwt_secret="change-me-in-production", sac_public_url="https://sac.example.com", cors_origins="https://sac.example.com", sac_security_enforce=True, ) with pytest.raises(RuntimeError, match="JWT_SECRET"): validate_security_settings(settings) def test_validate_security_settings_rejects_wildcard_cors(monkeypatch): settings = Settings( jwt_secret="strong-secret-value", sac_public_url="https://sac.example.com", cors_origins="*", sac_security_enforce=True, ) with pytest.raises(RuntimeError, match="CORS_ORIGINS"): validate_security_settings(settings)