"""Password + JWT primitives.""" from __future__ import annotations import time import pytest from ypms.auth.security import ( create_access_token, create_refresh_token, decode_token, hash_password, verify_password, ) def test_hash_password_returns_pbkdf2_prefix() -> None: h = hash_password("hunter2hunter2") assert h.startswith("$pbkdf2-sha256$") def test_verify_password_true_on_match_false_on_mismatch() -> None: h = hash_password("correcthorsebattery") assert verify_password("correcthorsebattery", h) is True assert verify_password("wrong", h) is False def test_access_token_carries_ypms_claims() -> None: tok = create_access_token( sub="chris", uid=1, roles=["DOES_SYSTEM_ADMIN"], assurance_level="admin", mfa_verified=False, ) claims = decode_token(tok) assert claims["sub"] == "chris" assert claims["uid"] == 1 assert claims["roles"] == ["DOES_SYSTEM_ADMIN"] assert claims["iam.assurance_level"] == "admin" assert claims["mfa_verified"] is False assert claims["type"] == "access" assert claims["exp"] > claims["iat"] >= int(time.time()) - 5 def test_refresh_token_has_type_refresh_and_carries_uid() -> None: tok = create_refresh_token(sub="chris", uid=42) claims = decode_token(tok) assert claims["type"] == "refresh" assert claims["sub"] == "chris" assert claims["uid"] == 42 assert "roles" not in claims assert "iam.assurance_level" not in claims def test_decode_invalid_token_raises() -> None: with pytest.raises(ValueError): decode_token("not-a-real-jwt")