mcp-security-framework 0.1.0__py3-none-any.whl → 1.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. mcp_security_framework/__init__.py +26 -15
  2. mcp_security_framework/cli/__init__.py +1 -1
  3. mcp_security_framework/cli/cert_cli.py +233 -197
  4. mcp_security_framework/cli/security_cli.py +324 -234
  5. mcp_security_framework/constants.py +21 -27
  6. mcp_security_framework/core/auth_manager.py +49 -20
  7. mcp_security_framework/core/cert_manager.py +398 -104
  8. mcp_security_framework/core/permission_manager.py +13 -9
  9. mcp_security_framework/core/rate_limiter.py +10 -0
  10. mcp_security_framework/core/security_manager.py +286 -229
  11. mcp_security_framework/examples/__init__.py +6 -0
  12. mcp_security_framework/examples/comprehensive_example.py +954 -0
  13. mcp_security_framework/examples/django_example.py +276 -202
  14. mcp_security_framework/examples/fastapi_example.py +897 -393
  15. mcp_security_framework/examples/flask_example.py +311 -200
  16. mcp_security_framework/examples/gateway_example.py +373 -214
  17. mcp_security_framework/examples/microservice_example.py +337 -172
  18. mcp_security_framework/examples/standalone_example.py +719 -478
  19. mcp_security_framework/examples/test_all_examples.py +572 -0
  20. mcp_security_framework/middleware/__init__.py +46 -55
  21. mcp_security_framework/middleware/auth_middleware.py +62 -63
  22. mcp_security_framework/middleware/fastapi_auth_middleware.py +179 -110
  23. mcp_security_framework/middleware/fastapi_middleware.py +156 -148
  24. mcp_security_framework/middleware/flask_auth_middleware.py +267 -107
  25. mcp_security_framework/middleware/flask_middleware.py +183 -157
  26. mcp_security_framework/middleware/mtls_middleware.py +106 -117
  27. mcp_security_framework/middleware/rate_limit_middleware.py +105 -101
  28. mcp_security_framework/middleware/security_middleware.py +109 -124
  29. mcp_security_framework/schemas/config.py +2 -1
  30. mcp_security_framework/schemas/models.py +19 -6
  31. mcp_security_framework/utils/cert_utils.py +14 -8
  32. mcp_security_framework/utils/datetime_compat.py +116 -0
  33. {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/METADATA +2 -1
  34. mcp_security_framework-1.1.1.dist-info/RECORD +84 -0
  35. tests/conftest.py +303 -0
  36. tests/test_cli/test_cert_cli.py +194 -174
  37. tests/test_cli/test_security_cli.py +274 -247
  38. tests/test_core/test_cert_manager.py +33 -19
  39. tests/test_core/test_security_manager.py +2 -2
  40. tests/test_examples/test_comprehensive_example.py +613 -0
  41. tests/test_examples/test_fastapi_example.py +290 -169
  42. tests/test_examples/test_flask_example.py +304 -162
  43. tests/test_examples/test_standalone_example.py +106 -168
  44. tests/test_integration/test_auth_flow.py +214 -198
  45. tests/test_integration/test_certificate_flow.py +181 -150
  46. tests/test_integration/test_fastapi_integration.py +140 -149
  47. tests/test_integration/test_flask_integration.py +144 -141
  48. tests/test_integration/test_standalone_integration.py +331 -300
  49. tests/test_middleware/test_fastapi_auth_middleware.py +745 -0
  50. tests/test_middleware/test_fastapi_middleware.py +147 -132
  51. tests/test_middleware/test_flask_auth_middleware.py +696 -0
  52. tests/test_middleware/test_flask_middleware.py +201 -179
  53. tests/test_middleware/test_security_middleware.py +151 -130
  54. tests/test_utils/test_datetime_compat.py +147 -0
  55. mcp_security_framework-0.1.0.dist-info/RECORD +0 -76
  56. {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/WHEEL +0 -0
  57. {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/entry_points.txt +0 -0
  58. {mcp_security_framework-0.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,147 @@
1
+ """
2
+ Tests for Datetime Compatibility Module
3
+
4
+ This module contains tests for the datetime compatibility functions that
5
+ handle certificate datetime fields across different cryptography versions.
6
+
7
+ Test Coverage:
8
+ - Compatibility with cryptography>=42 (UTC fields)
9
+ - Compatibility with cryptography<42 (legacy fields)
10
+ - Timezone normalization
11
+ - Version detection
12
+ - Error handling
13
+
14
+ Author: Vasiliy Zdanovskiy
15
+ email: vasilyvz@gmail.com
16
+ """
17
+
18
+ from datetime import datetime, timezone
19
+ from unittest.mock import Mock, patch
20
+
21
+ import pytest
22
+
23
+ from mcp_security_framework.utils.datetime_compat import (
24
+ get_not_valid_after_utc,
25
+ get_not_valid_before_utc,
26
+ is_cryptography_42_plus,
27
+ )
28
+
29
+
30
+ class TestDatetimeCompatibility:
31
+ """Test suite for datetime compatibility functions."""
32
+
33
+ def test_get_not_valid_before_utc_with_utc_field(self):
34
+ """Test get_not_valid_before_utc with cryptography>=42 UTC field."""
35
+ # Mock certificate with UTC field (cryptography>=42)
36
+ mock_cert = Mock()
37
+ expected_time = datetime.now(timezone.utc)
38
+ mock_cert.not_valid_before_utc = expected_time
39
+ mock_cert.not_valid_before = datetime.now() # Legacy field
40
+
41
+ result = get_not_valid_before_utc(mock_cert)
42
+
43
+ assert result == expected_time
44
+ assert result.tzinfo == timezone.utc
45
+
46
+ def test_get_not_valid_before_utc_with_legacy_field(self):
47
+ """Test get_not_valid_before_utc with cryptography<42 legacy field."""
48
+ # Mock certificate without UTC field (cryptography<42)
49
+ mock_cert = Mock()
50
+ mock_cert.not_valid_before_utc = None # Field doesn't exist
51
+ naive_time = datetime.now()
52
+ mock_cert.not_valid_before = naive_time
53
+
54
+ result = get_not_valid_before_utc(mock_cert)
55
+
56
+ assert result.tzinfo == timezone.utc
57
+ assert result.replace(tzinfo=None) == naive_time
58
+
59
+ def test_get_not_valid_before_utc_with_legacy_field_already_utc(self):
60
+ """Test get_not_valid_before_utc with legacy field that's already UTC."""
61
+ # Mock certificate without UTC field but legacy field is already UTC
62
+ mock_cert = Mock()
63
+ mock_cert.not_valid_before_utc = None # Field doesn't exist
64
+ utc_time = datetime.now(timezone.utc)
65
+ mock_cert.not_valid_before = utc_time
66
+
67
+ result = get_not_valid_before_utc(mock_cert)
68
+
69
+ assert result == utc_time
70
+ assert result.tzinfo == timezone.utc
71
+
72
+ def test_get_not_valid_after_utc_with_utc_field(self):
73
+ """Test get_not_valid_after_utc with cryptography>=42 UTC field."""
74
+ # Mock certificate with UTC field (cryptography>=42)
75
+ mock_cert = Mock()
76
+ expected_time = datetime.now(timezone.utc)
77
+ mock_cert.not_valid_after_utc = expected_time
78
+ mock_cert.not_valid_after = datetime.now() # Legacy field
79
+
80
+ result = get_not_valid_after_utc(mock_cert)
81
+
82
+ assert result == expected_time
83
+ assert result.tzinfo == timezone.utc
84
+
85
+ def test_get_not_valid_after_utc_with_legacy_field(self):
86
+ """Test get_not_valid_after_utc with cryptography<42 legacy field."""
87
+ # Mock certificate without UTC field (cryptography<42)
88
+ mock_cert = Mock()
89
+ mock_cert.not_valid_after_utc = None # Field doesn't exist
90
+ naive_time = datetime.now()
91
+ mock_cert.not_valid_after = naive_time
92
+
93
+ result = get_not_valid_after_utc(mock_cert)
94
+
95
+ assert result.tzinfo == timezone.utc
96
+ assert result.replace(tzinfo=None) == naive_time
97
+
98
+ def test_get_not_valid_after_utc_with_legacy_field_already_utc(self):
99
+ """Test get_not_valid_after_utc with legacy field that's already UTC."""
100
+ # Mock certificate without UTC field but legacy field is already UTC
101
+ mock_cert = Mock()
102
+ mock_cert.not_valid_after_utc = None # Field doesn't exist
103
+ utc_time = datetime.now(timezone.utc)
104
+ mock_cert.not_valid_after = utc_time
105
+
106
+ result = get_not_valid_after_utc(mock_cert)
107
+
108
+ assert result == utc_time
109
+ assert result.tzinfo == timezone.utc
110
+
111
+ def test_is_cryptography_42_plus_basic(self):
112
+ """Test is_cryptography_42_plus basic functionality."""
113
+ # This test just verifies the function doesn't crash
114
+ # and returns a boolean value
115
+ result = is_cryptography_42_plus()
116
+
117
+ assert isinstance(result, bool)
118
+
119
+ def test_compatibility_integration(self):
120
+ """Test integration of compatibility functions with real certificate-like objects."""
121
+ # Test with object that has both fields (simulating cryptography>=42)
122
+ mock_cert_new = Mock()
123
+ utc_time = datetime.now(timezone.utc)
124
+ mock_cert_new.not_valid_before_utc = utc_time
125
+ mock_cert_new.not_valid_after_utc = utc_time
126
+
127
+ before_result = get_not_valid_before_utc(mock_cert_new)
128
+ after_result = get_not_valid_after_utc(mock_cert_new)
129
+
130
+ assert before_result == utc_time
131
+ assert after_result == utc_time
132
+
133
+ # Test with object that has only legacy fields (simulating cryptography<42)
134
+ mock_cert_old = Mock()
135
+ naive_time = datetime.now()
136
+ mock_cert_old.not_valid_before_utc = None
137
+ mock_cert_old.not_valid_after_utc = None
138
+ mock_cert_old.not_valid_before = naive_time
139
+ mock_cert_old.not_valid_after = naive_time
140
+
141
+ before_result = get_not_valid_before_utc(mock_cert_old)
142
+ after_result = get_not_valid_after_utc(mock_cert_old)
143
+
144
+ assert before_result.tzinfo == timezone.utc
145
+ assert after_result.tzinfo == timezone.utc
146
+ assert before_result.replace(tzinfo=None) == naive_time
147
+ assert after_result.replace(tzinfo=None) == naive_time
@@ -1,76 +0,0 @@
1
- mcp_security_framework/__init__.py,sha256=Q7FHjxcxvQn4JAFHMuHflyCHLR3F7-jmqMx7YaWgPtU,3136
2
- mcp_security_framework/constants.py,sha256=6jXpxTXpua76NgL1KkRYX3tAobCgtY3_4MGM2a1Blg0,5362
3
- mcp_security_framework/cli/__init__.py,sha256=cPLJ5iZYxSomXFjA4-IPWE3hmMx6ryiWaebyJSW68bc,369
4
- mcp_security_framework/cli/cert_cli.py,sha256=QW2YciGE5jKdfzYMwXCn-znNm22VhAaSHk4qH4tcp2w,19129
5
- mcp_security_framework/cli/security_cli.py,sha256=fmYVT03NbR7PrO6qUa9L1FQhTTPd1ZMFIB6H6nWLqOU,27993
6
- mcp_security_framework/core/__init__.py,sha256=LiX8_M5qWiTXccJFjSLxup9emhklp-poq57SvznsKEg,1729
7
- mcp_security_framework/core/auth_manager.py,sha256=ndIlK-B0rubj7fPm6hsNK0CmBVoZDES8XE4q6LUWCHo,38356
8
- mcp_security_framework/core/cert_manager.py,sha256=DSr9Z4ihyRXDYutsZspcTvHIlDSLy-yEk-BpwSBY4BE,68254
9
- mcp_security_framework/core/permission_manager.py,sha256=WOownY60_tb_MxI15XKfJt-FxCHzDaZQcqMWVq3FqKI,26360
10
- mcp_security_framework/core/rate_limiter.py,sha256=4IPs8ED35-iylEa2cHYcRB1IcyyxOt_StcEI6Pug0Tc,20431
11
- mcp_security_framework/core/security_manager.py,sha256=_6VmbN_MFgyV8igIvKQMBQDQLfKLu9bQhrP3YNIuAOM,38082
12
- mcp_security_framework/core/ssl_manager.py,sha256=nCDrukaELONQs_uAfb30g69HDxRp2u4k0Bpq8eJH6Zo,27718
13
- mcp_security_framework/examples/__init__.py,sha256=RW-qTe-Fu3Hbl1Kyd58pWqYan92cmW-y0g2wEVCK850,1909
14
- mcp_security_framework/examples/django_example.py,sha256=_ao52mIt0a0SofiyJfPfK3lVnMx7Z5gS4jP3pJkn4iw,23306
15
- mcp_security_framework/examples/fastapi_example.py,sha256=cLD8wDl2CSDuW7kjhFXT0pASLNo0NWjmoC31it2txiQ,18230
16
- mcp_security_framework/examples/flask_example.py,sha256=OWvHbKzgknJVO1CKjdCeV1atzfATbmjV_YoPudGrX6Q,19129
17
- mcp_security_framework/examples/gateway_example.py,sha256=AkZn7NMgI7fURWXQS_-j3TSbdKsKpM5uhrQhAi7AddI,29727
18
- mcp_security_framework/examples/microservice_example.py,sha256=wTH03ddF5xc0tfqKNgdBlCoyiZ-Uy65uNq8L7F1XlQs,26186
19
- mcp_security_framework/examples/standalone_example.py,sha256=DEugeIFOHiVWH6fWzNMM-fIKH0OVpIkzeBWHtzut1m0,20820
20
- mcp_security_framework/middleware/__init__.py,sha256=wSBfpfdrz4ErqhwCOJI1uxbQ5Q22_2HdjrxmwwWuj0o,8027
21
- mcp_security_framework/middleware/auth_middleware.py,sha256=8fUgY8PfL_UVSbkbXUC5dqF_oISyuA8LaIvZjAD7U0g,10230
22
- mcp_security_framework/middleware/fastapi_auth_middleware.py,sha256=wyzQO_xX5y6G-FGnC9xcEUfG_IJ03jSgn6faQXGppyg,15607
23
- mcp_security_framework/middleware/fastapi_middleware.py,sha256=J8olLT3SICbM-NJ2m11cPkOfhREtlJHYk5ENfggbuU4,27260
24
- mcp_security_framework/middleware/flask_auth_middleware.py,sha256=ETsZQEaPiO9p8pr_p3gNIZP-yxj4lZZWhqyQp9WLDc8,16120
25
- mcp_security_framework/middleware/flask_middleware.py,sha256=wtHafpEgOvA8ZEIzJQzt-LqbIrcFWd1sz8QJXNpgkEU,21083
26
- mcp_security_framework/middleware/mtls_middleware.py,sha256=TsI9BwFkX98KqG9E1bpFFOrcA8vsaumRc0GH6dOEHRs,14694
27
- mcp_security_framework/middleware/rate_limit_middleware.py,sha256=EgjF7mzhkdgfL4nT4eLtKchWmmwaa50WCuIVwYwl_ac,13661
28
- mcp_security_framework/middleware/security_middleware.py,sha256=aQDt9ktMzs0KzNq_aW_23dfOSTmIrWHNj_ps0O7MK40,17804
29
- mcp_security_framework/schemas/__init__.py,sha256=lefkbRlbj2ICfasSj51MQ04o3z1YycnbnknSJCFfXbU,2590
30
- mcp_security_framework/schemas/config.py,sha256=dMlMum-pCWMwYoqBm14dUD725pOW63dYPfIqXv_0maQ,25816
31
- mcp_security_framework/schemas/models.py,sha256=rDX0HTqmnI2jWsUGhmkDdLXk6ijuUnE5FGj6IZPVTW8,26789
32
- mcp_security_framework/schemas/responses.py,sha256=nVXaqF5GTSprXTa_wiUEu38nvSw9WAXtKViAJNbO-Xg,23206
33
- mcp_security_framework/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- mcp_security_framework/utils/__init__.py,sha256=wwwdmQYHTSz0Puvs9FD6aIKmWp3NFARe3JPWNH-b_wk,3098
35
- mcp_security_framework/utils/cert_utils.py,sha256=5PHbrksa8Cub66v8SuI3ljCNgc0jN3pBto1Q2AIddIc,17140
36
- mcp_security_framework/utils/crypto_utils.py,sha256=OH2V7_C3FjStxFTIXMUPfNXZuWG2-QjgoBrIH4Lv4p0,12392
37
- mcp_security_framework/utils/validation_utils.py,sha256=e9BX3kw9gdXSmFsc7lmG-qnzSlK0-Ynn7Xs4uKHquF4,16279
38
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- tests/test_cli/test_cert_cli.py,sha256=_7_KsKDYCeNGiPmmzIsjEfxaavwu2I5q_mTXmbYfKtw,15276
41
- tests/test_cli/test_security_cli.py,sha256=oMEUEzt-B-UR-acAzUa-BR1YDOGEwdmKiSy-MIuflGE,25926
42
- tests/test_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- tests/test_core/test_auth_manager.py,sha256=tyJUe3yBP95SFwbhSr_IloKhEQw0BuEdvjAC1Hnwu4s,22540
44
- tests/test_core/test_cert_manager.py,sha256=v1Czmn-I6XcSLglmcForLyjYsIOsHjys9QbiQQEAf6U,36035
45
- tests/test_core/test_permission_manager.py,sha256=0XeghWXZqVpKyyRuhuDu1dkLUSwuZaFWkRQxQhkkFVI,14966
46
- tests/test_core/test_rate_limiter.py,sha256=YzzlhlxZm-A7YGMiIV8LXDA0zmb_6uRF9GRx9s21Q0U,22544
47
- tests/test_core/test_security_manager.py,sha256=y8klHTMeBoh16wI-10-7gd92T7ZpmuPaSmDtfWM88Ns,35007
48
- tests/test_core/test_ssl_manager.py,sha256=Vm_Nw4SoVro_iwPPc_uD9CwzXpVBkGyVH7EqDtHawvU,20362
49
- tests/test_examples/__init__.py,sha256=VC0N1wB9d01Acnqfos-9x68o23xxHkRhAh4-1qJKUTc,157
50
- tests/test_examples/test_fastapi_example.py,sha256=JORSEN3054b_X4yjyOncQsRCPSLjCyPNOE9w9WwacVg,10025
51
- tests/test_examples/test_flask_example.py,sha256=1UeNKxDMrrStlfPjIa2vuE70IN-D8aHDOMIiph13JrY,9113
52
- tests/test_examples/test_standalone_example.py,sha256=vRiDitsxr_PcNyhjAaUaEm_P3zPS4ssPIS21SK5ipB0,10829
53
- tests/test_integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- tests/test_integration/test_auth_flow.py,sha256=98838l6JZF03-aqbGnjmiTugrkHBDsOAsRTEBtNDxfA,19175
55
- tests/test_integration/test_certificate_flow.py,sha256=QscOQCq0O5VNL-qQx07sn7w5EEl1rnxonEgDzKL6nhw,19957
56
- tests/test_integration/test_fastapi_integration.py,sha256=KJETHjecYbXcMK6hW7oKb2qltyK8Ywd97-iTOXH1YkQ,13480
57
- tests/test_integration/test_flask_integration.py,sha256=UPRLWz5W3ZWP-ka8xDB2iJVwz86ixwxOA3rXNGWV8_g,15629
58
- tests/test_integration/test_standalone_integration.py,sha256=wB0E4D_dBV8dmeHqm9BIHPOtlSNA7fJ-HGjsDgQelKo,18941
59
- tests/test_middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
- tests/test_middleware/test_fastapi_middleware.py,sha256=43U1PGHDa9a8AnvJpbuyUE1psDuvj2-g64dWkEuqTBM,21150
61
- tests/test_middleware/test_flask_middleware.py,sha256=OfucOhChC3rr8UdSYz2EWQzCtA0oalMqzDxdiT1tNOQ,23364
62
- tests/test_middleware/test_security_middleware.py,sha256=BSxMNO45bpRYCOA7wmhwhlOcJSxPwip0BaD0EpYeAxM,19426
63
- tests/test_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- tests/test_schemas/test_config.py,sha256=Bp_yZ_HBIl7jcR7Wb1S9iCB0tCu_Ov26YKHTulDs1RU,29430
65
- tests/test_schemas/test_models.py,sha256=bBeZOPqveuVJuEi_BTVWdVsdj08JXJTEFwvBM4eFRVU,34311
66
- tests/test_schemas/test_responses.py,sha256=ZSbO7A3ThPBovTXO8PFF-2ONWAjJx2dMOoV2lQIfd8s,40774
67
- tests/test_schemas/test_serialization.py,sha256=jCugAyrdD6Mw1U7Kxni9oTukarZmMMl6KUcl6cq_NTk,18599
68
- tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
- tests/test_utils/test_cert_utils.py,sha256=2k1kUCJy0T2HPBwOcU5USGfEBQZ_rGzumAGkDdywLak,21232
70
- tests/test_utils/test_crypto_utils.py,sha256=yEb4hzG6-irj2DPoXY0DUboJfbeR87ussgTuBpxLGz4,20737
71
- tests/test_utils/test_validation_utils.py,sha256=lus_wHJ2WyVnBGQ28S7dSv78uWcCIuLhn5uflJw-uGw,18569
72
- mcp_security_framework-0.1.0.dist-info/METADATA,sha256=fgGhutpMQy0ILWfplGySOAXpwPKudQRzQAj2wdsMzRQ,11680
73
- mcp_security_framework-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
74
- mcp_security_framework-0.1.0.dist-info/entry_points.txt,sha256=qBh92fVDmd1m2f3xeW0hTu3Ksg8QfGJyV8UEkdA2itg,142
75
- mcp_security_framework-0.1.0.dist-info/top_level.txt,sha256=ifUiGrTDcD574MXSOoAN2rp2wpUvWlb4jD9LTUgDWCA,29
76
- mcp_security_framework-0.1.0.dist-info/RECORD,,