test_security.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import unittest
  2. from utils.security import (
  3. generate_gateway_session_id,
  4. hash_gateway_session_id,
  5. constant_time_equals
  6. )
  7. class TestSecurity(unittest.TestCase):
  8. def test_generate_gateway_session_id_format(self):
  9. session_id = generate_gateway_session_id()
  10. # Should start with GWS_
  11. self.assertTrue(session_id.startswith('GWS_'))
  12. # Should be long enough (GWS_ + 32+ chars)
  13. self.assertGreater(len(session_id), 36)
  14. def test_generate_gateway_session_id_uniqueness(self):
  15. # Generate multiple IDs and ensure they're all different
  16. ids = [generate_gateway_session_id() for _ in range(100)]
  17. unique_ids = set(ids)
  18. self.assertEqual(len(ids), len(unique_ids))
  19. def test_hash_gateway_session_id_consistent(self):
  20. session_id = 'GWS_test123'
  21. hash1 = hash_gateway_session_id(session_id)
  22. hash2 = hash_gateway_session_id(session_id)
  23. self.assertEqual(hash1, hash2)
  24. def test_hash_gateway_session_id_different_for_different_inputs(self):
  25. session_id_1 = 'GWS_test123'
  26. session_id_2 = 'GWS_test456'
  27. hash1 = hash_gateway_session_id(session_id_1)
  28. hash2 = hash_gateway_session_id(session_id_2)
  29. self.assertNotEqual(hash1, hash2)
  30. def test_hash_gateway_session_id_length(self):
  31. session_id = 'GWS_xyz'
  32. hashed = hash_gateway_session_id(session_id)
  33. # SHA256 produces 64 hex characters
  34. self.assertEqual(len(hashed), 64)
  35. def test_hash_gateway_session_id_raises_on_empty(self):
  36. with self.assertRaises(ValueError) as context:
  37. hash_gateway_session_id('')
  38. self.assertIn('gateway_session_id is required', str(context.exception))
  39. def test_hash_gateway_session_id_raises_on_none(self):
  40. with self.assertRaises(ValueError) as context:
  41. hash_gateway_session_id(None)
  42. self.assertIn('gateway_session_id is required', str(context.exception))
  43. def test_hash_gateway_session_id_handles_whitespace(self):
  44. # Hash should handle whitespace consistently
  45. session_id_with_spaces = ' GWS_test '
  46. hash_result = hash_gateway_session_id(session_id_with_spaces)
  47. # Should be a valid hash
  48. self.assertEqual(len(hash_result), 64)
  49. # Same input should give same hash
  50. hash_result_2 = hash_gateway_session_id(session_id_with_spaces)
  51. self.assertEqual(hash_result, hash_result_2)
  52. def test_constant_time_equals_true_for_same_strings(self):
  53. result = constant_time_equals('test123', 'test123')
  54. self.assertTrue(result)
  55. def test_constant_time_equals_false_for_different_strings(self):
  56. result = constant_time_equals('test123', 'test456')
  57. self.assertFalse(result)
  58. def test_constant_time_equals_handles_none(self):
  59. result1 = constant_time_equals(None, None)
  60. self.assertTrue(result1)
  61. result2 = constant_time_equals('test', None)
  62. self.assertFalse(result2)
  63. result3 = constant_time_equals(None, 'test')
  64. self.assertFalse(result3)
  65. def test_constant_time_equals_handles_empty_strings(self):
  66. result = constant_time_equals('', '')
  67. self.assertTrue(result)
  68. def test_constant_time_equals_case_sensitive(self):
  69. result = constant_time_equals('Test', 'test')
  70. self.assertFalse(result)
  71. def test_generate_session_id_url_safe(self):
  72. # URL-safe base64 should not contain +, /, or =
  73. session_id = generate_gateway_session_id()
  74. token_part = session_id[4:] # Remove 'GWS_' prefix
  75. self.assertNotIn('+', token_part)
  76. self.assertNotIn('/', token_part)
  77. # May or may not have = padding, but should be URL-safe
  78. def test_hash_deterministic(self):
  79. # Same input should always produce same output
  80. session_id = 'GWS_deterministic_test'
  81. hashes = [hash_gateway_session_id(session_id) for _ in range(10)]
  82. self.assertEqual(len(set(hashes)), 1)
  83. if __name__ == '__main__':
  84. unittest.main()