test_crypto_utils.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import pytest
  2. import os
  3. from cryptography.fernet import Fernet
  4. from crypto_utils import (
  5. get_api_key_hash,
  6. is_dev_mode,
  7. get_encryption_key,
  8. encrypt_json,
  9. decrypt_json,
  10. )
  11. class TestApiKeyHash:
  12. def test_hash_is_deterministic(self):
  13. """Same API key should produce same hash."""
  14. api_key = "test-key-123"
  15. hash1 = get_api_key_hash(api_key)
  16. hash2 = get_api_key_hash(api_key)
  17. assert hash1 == hash2
  18. def test_hash_is_16_chars(self):
  19. """Hash should be 16 characters long."""
  20. api_key = "test-key-123"
  21. hash_val = get_api_key_hash(api_key)
  22. assert len(hash_val) == 16
  23. def test_different_keys_different_hashes(self):
  24. """Different API keys should produce different hashes."""
  25. hash1 = get_api_key_hash("key1")
  26. hash2 = get_api_key_hash("key2")
  27. assert hash1 != hash2
  28. class TestDevMode:
  29. def test_dev_mode_true(self):
  30. """Dev mode should be enabled when env var is 'true'."""
  31. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "true"
  32. assert is_dev_mode() is True
  33. def test_dev_mode_1(self):
  34. """Dev mode should be enabled when env var is '1'."""
  35. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "1"
  36. assert is_dev_mode() is True
  37. def test_dev_mode_yes(self):
  38. """Dev mode should be enabled when env var is 'yes'."""
  39. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "yes"
  40. assert is_dev_mode() is True
  41. def test_dev_mode_false(self):
  42. """Dev mode should be disabled when env var is 'false'."""
  43. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "false"
  44. assert is_dev_mode() is False
  45. def test_dev_mode_unset(self):
  46. """Dev mode should be disabled when env var is not set."""
  47. if "LETTA_SWITCHBOARD_DEV_MODE" in os.environ:
  48. del os.environ["LETTA_SWITCHBOARD_DEV_MODE"]
  49. assert is_dev_mode() is False
  50. class TestEncryption:
  51. def test_encrypt_decrypt_roundtrip(self, encryption_key):
  52. """Data should survive encryption/decryption roundtrip."""
  53. original_data = {
  54. "id": "test-123",
  55. "message": "Hello world",
  56. "nested": {"key": "value"}
  57. }
  58. encrypted = encrypt_json(original_data, encryption_key)
  59. decrypted = decrypt_json(encrypted, encryption_key)
  60. assert decrypted == original_data
  61. def test_encrypted_data_is_bytes(self, encryption_key):
  62. """Encrypted data should be bytes."""
  63. data = {"test": "data"}
  64. encrypted = encrypt_json(data, encryption_key)
  65. assert isinstance(encrypted, bytes)
  66. def test_dev_mode_plaintext(self):
  67. """In dev mode, data should be plaintext JSON."""
  68. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "true"
  69. data = {"test": "data", "number": 123}
  70. key = b"ignored-in-dev-mode"
  71. encrypted = encrypt_json(data, key)
  72. assert isinstance(encrypted, bytes)
  73. # Should be valid JSON
  74. import json
  75. parsed = json.loads(encrypted)
  76. assert parsed == data
  77. def test_dev_mode_decrypt(self):
  78. """In dev mode, decrypt should parse plaintext JSON."""
  79. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "true"
  80. data = {"test": "data"}
  81. key = b"ignored"
  82. encrypted = encrypt_json(data, key)
  83. decrypted = decrypt_json(encrypted, key)
  84. assert decrypted == data
  85. def test_production_mode_encrypted(self):
  86. """In production mode, data should be encrypted (not plaintext)."""
  87. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "false"
  88. data = {"test": "secret"}
  89. key = Fernet.generate_key()
  90. encrypted = encrypt_json(data, key)
  91. # Should NOT be valid JSON
  92. import json
  93. with pytest.raises(json.JSONDecodeError):
  94. json.loads(encrypted)
  95. def test_wrong_key_fails(self, encryption_key):
  96. """Decrypting with wrong key should fail."""
  97. os.environ["LETTA_SWITCHBOARD_DEV_MODE"] = "false"
  98. data = {"test": "data"}
  99. encrypted = encrypt_json(data, encryption_key)
  100. wrong_key = Fernet.generate_key()
  101. with pytest.raises(Exception):
  102. decrypt_json(encrypted, wrong_key)