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

90 lines
3.6 KiB
Python

from datetime import timedelta
from django.utils import timezone
from infrasynth.security.models import TwoFactorConfig
from infrasynth.security.two_factor.middleware import TwoFactorMiddleware
from infrasynth.security.two_factor.utils import (
generate_pre_auth_token,
get_pre_auth_expiry,
)
class TestPreAuthUtils:
def test_generate_pre_auth_token_length(self):
token = generate_pre_auth_token()
assert len(token) == 64
def test_generate_pre_auth_token_unique(self):
assert generate_pre_auth_token() != generate_pre_auth_token()
def test_get_pre_auth_expiry(self):
before = timezone.now()
expiry = get_pre_auth_expiry(minutes=5)
after = timezone.now()
assert before + timedelta(minutes=5) <= expiry <= after + timedelta(minutes=5)
class _Request:
def __init__(self, user, path="/api/features/active/"):
self.user = user
self.path = path
class TestTwoFactorMiddleware:
def test_anonymous_passes(self, rf, db):
request = rf.get("/api/features/active/")
request.user = type("Anon", (), {"is_authenticated": False})()
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None
def test_user_without_config_passes(self, rf, user):
request = rf.get("/api/features/active/")
request.user = user
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None
def test_disabled_config_passes(self, rf, user):
TwoFactorConfig.objects.create(user=user, is_enabled=False, is_configured=True)
request = rf.get("/api/features/active/")
request.user = user
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None
def test_unconfigured_enabled_passes(self, rf, user):
TwoFactorConfig.objects.create(user=user, is_enabled=True, is_configured=False)
request = rf.get("/api/features/active/")
request.user = user
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None
def test_redirects_when_2fa_required(self, rf, user):
TwoFactorConfig.objects.create(user=user, is_enabled=True, is_configured=True)
request = rf.get("/api/features/active/")
request.user = user
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is not None
assert result.status_code == 302
assert result.url == "/api/auth/2fa/verify/"
def test_exempt_paths_not_redirected(self, rf, user):
TwoFactorConfig.objects.create(user=user, is_enabled=True, is_configured=True)
request = rf.get("/api/auth/check/")
request.user = user
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None
def test_admin_path_not_redirected(self, rf, user):
TwoFactorConfig.objects.create(user=user, is_enabled=True, is_configured=True)
request = rf.get("/admin/")
request.user = user
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None
def test_verified_user_not_redirected(self, rf, user):
TwoFactorConfig.objects.create(user=user, is_enabled=True, is_configured=True)
request = rf.get("/api/features/active/")
request.user = user
request._2fa_verified = True
result = TwoFactorMiddleware(get_response=lambda r: None).process_request(request)
assert result is None