infrasynth-backend-kit/tests/test_security/test_api_keys.py
2026-08-28 14:38:47 -05:00

91 lines
3.4 KiB
Python

from django.contrib.auth.hashers import make_password
from rest_framework import status
from infrasynth.security.auth.middleware import JWTAuthenticationMiddleware
from infrasynth.security.models import APIKey
class TestAPIKeyViewSet:
def test_create_returns_full_key_once(self, authenticated_client):
resp = authenticated_client.post(
"/api/auth/api-keys/",
{"name": "CI Key", "scopes": ["read:users"]},
format="json",
)
assert resp.status_code == status.HTTP_201_CREATED
data = resp.json()
assert "key" in data
assert "prefix" in data
assert data["key"].startswith(data["prefix"] + ".")
def test_created_key_authenticates(self, authenticated_client):
resp = authenticated_client.post(
"/api/auth/api-keys/",
{"name": "CI Key", "scopes": ["read:users"]},
format="json",
)
full_key = resp.json()["key"]
from rest_framework.test import APIClient
client = APIClient()
client.credentials(HTTP_X_API_KEY=full_key)
check = client.get("/api/auth/check/")
assert check.status_code == status.HTTP_200_OK
def test_list_keys(self, authenticated_client, user):
APIKey.objects.create(
name="Old Key",
prefix="prefix01",
key_hash=make_password("secret"),
created_by=user,
)
resp = authenticated_client.get("/api/auth/api-keys/")
assert resp.status_code == status.HTTP_200_OK
assert resp.json()["count"] == 1
def test_list_never_exposes_hash(self, authenticated_client, user):
APIKey.objects.create(
name="Old Key",
prefix="prefix01",
key_hash=make_password("secret"),
created_by=user,
)
resp = authenticated_client.get("/api/auth/api-keys/")
result = resp.json()["results"][0]
assert "key" not in result
assert "key_hash" not in result
assert result["prefix"] == "prefix01"
def test_delete_key(self, authenticated_client, user):
key = APIKey.objects.create(
name="Old Key",
prefix="prefix01",
key_hash=make_password("secret"),
created_by=user,
)
resp = authenticated_client.delete(f"/api/auth/api-keys/{key.pk}/")
assert resp.status_code == status.HTTP_204_NO_CONTENT
assert not APIKey.objects.filter(pk=key.pk).exists()
def test_requires_auth(self, api_client):
resp = api_client.get("/api/auth/api-keys/")
assert resp.status_code == status.HTTP_401_UNAUTHORIZED
class TestJWTAuthenticationMiddleware:
def test_ignores_anonymous_requests(self, rf, db):
request = rf.get("/api/features/active/")
request.user = type("Anon", (), {"is_anonymous": True})()
JWTAuthenticationMiddleware(get_response=lambda r: None).process_request(request)
assert request.user.is_anonymous
def test_populates_user_from_cookie(self, rf, user):
from rest_framework_simplejwt.tokens import RefreshToken
from infrasynth.shared.crypto import encrypt
request = rf.get("/api/features/active/")
request.COOKIES["access_token"] = encrypt(str(RefreshToken.for_user(user).access_token))
request.user = type("Anon", (), {"is_anonymous": True})()
JWTAuthenticationMiddleware(get_response=lambda r: None).process_request(request)
assert request.user == user