Files
Cognitive_Agent/tests/unit/test_auth.py

93 lines
3.2 KiB
Python
Executable File

from __future__ import annotations
import unittest
from cognitive_agent.auth import (
AuthConfig,
SessionCodec,
SlidingWindowLimiter,
hash_password,
is_json_content_type,
origin_matches_host,
verify_password,
)
def auth_config() -> AuthConfig:
return AuthConfig(
enabled=True,
username="demo-user",
password_hash=hash_password(
"correct horse battery staple",
salt=b"0123456789abcdef",
iterations=100_000,
),
session_secret=b"s" * 64,
session_ttl_seconds=3600,
login_attempts=3,
login_window_seconds=60,
requests_per_minute=10,
trust_proxy_headers=False,
)
class AuthenticationUnitTests(unittest.TestCase):
def test_password_hash_verification(self) -> None:
encoded = auth_config().password_hash
self.assertTrue(verify_password("correct horse battery staple", encoded))
self.assertFalse(verify_password("wrong password", encoded))
self.assertNotIn("correct horse battery staple", encoded)
def test_signed_session_rejects_tampering_and_expiry(self) -> None:
codec = SessionCodec(auth_config())
token = codec.issue("demo-user", now=1000)
self.assertEqual(codec.verify(token, now=1001), "demo-user")
self.assertIsNone(codec.verify(token + "x", now=1001))
self.assertIsNone(codec.verify(token, now=4600))
def test_sliding_window_limiter_returns_retry_after(self) -> None:
limiter = SlidingWindowLimiter(limit=2, window_seconds=60)
limiter.record("client", now=100)
limiter.record("client", now=110)
self.assertEqual(limiter.retry_after("client", now=120), 40)
self.assertEqual(limiter.retry_after("client", now=161), 0)
def test_json_content_type_is_exact_but_allows_parameters(self) -> None:
self.assertTrue(is_json_content_type("application/json"))
self.assertTrue(is_json_content_type("Application/JSON; charset=utf-8"))
self.assertFalse(is_json_content_type("text/plain"))
self.assertFalse(is_json_content_type("application/problem+json"))
self.assertFalse(is_json_content_type(""))
def test_origin_match_uses_scheme_host_and_effective_port(self) -> None:
self.assertTrue(
origin_matches_host("http://127.0.0.1:8000", "127.0.0.1:8000", "http")
)
self.assertTrue(origin_matches_host("http://example.test", "EXAMPLE.test:80", "http"))
self.assertTrue(origin_matches_host("http://[::1]:8000", "[::1]:8000", "http"))
self.assertFalse(
origin_matches_host("http://localhost:8000", "127.0.0.1:8000", "http")
)
self.assertFalse(
origin_matches_host("https://127.0.0.1:8000", "127.0.0.1:8000", "http")
)
self.assertFalse(
origin_matches_host("http://127.0.0.1:8001", "127.0.0.1:8000", "http")
)
self.assertFalse(origin_matches_host("null", "127.0.0.1:8000", "http"))
self.assertFalse(
origin_matches_host(
"http://127.0.0.1:8000/extra",
"127.0.0.1:8000",
"http",
)
)
if __name__ == "__main__":
unittest.main()