mcp-security-framework 1.1.0__py3-none-any.whl → 1.1.2__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 +41 -22
  7. mcp_security_framework/core/cert_manager.py +210 -147
  8. mcp_security_framework/core/permission_manager.py +9 -9
  9. mcp_security_framework/core/rate_limiter.py +2 -2
  10. mcp_security_framework/core/security_manager.py +284 -229
  11. mcp_security_framework/examples/__init__.py +6 -0
  12. mcp_security_framework/examples/comprehensive_example.py +349 -279
  13. mcp_security_framework/examples/django_example.py +247 -206
  14. mcp_security_framework/examples/fastapi_example.py +315 -283
  15. mcp_security_framework/examples/flask_example.py +274 -203
  16. mcp_security_framework/examples/gateway_example.py +304 -237
  17. mcp_security_framework/examples/microservice_example.py +258 -189
  18. mcp_security_framework/examples/standalone_example.py +255 -230
  19. mcp_security_framework/examples/test_all_examples.py +151 -135
  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 +119 -118
  23. mcp_security_framework/middleware/fastapi_middleware.py +156 -148
  24. mcp_security_framework/middleware/flask_auth_middleware.py +160 -147
  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 +18 -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-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/METADATA +4 -3
  34. mcp_security_framework-1.1.2.dist-info/RECORD +84 -0
  35. tests/conftest.py +63 -66
  36. tests/test_cli/test_cert_cli.py +184 -146
  37. tests/test_cli/test_security_cli.py +274 -247
  38. tests/test_core/test_cert_manager.py +24 -10
  39. tests/test_core/test_security_manager.py +2 -2
  40. tests/test_examples/test_comprehensive_example.py +190 -137
  41. tests/test_examples/test_fastapi_example.py +124 -101
  42. tests/test_examples/test_flask_example.py +124 -101
  43. tests/test_examples/test_standalone_example.py +73 -80
  44. tests/test_integration/test_auth_flow.py +213 -197
  45. tests/test_integration/test_certificate_flow.py +180 -149
  46. tests/test_integration/test_fastapi_integration.py +108 -111
  47. tests/test_integration/test_flask_integration.py +141 -140
  48. tests/test_integration/test_standalone_integration.py +290 -259
  49. tests/test_middleware/test_fastapi_auth_middleware.py +195 -174
  50. tests/test_middleware/test_fastapi_middleware.py +147 -132
  51. tests/test_middleware/test_flask_auth_middleware.py +260 -202
  52. tests/test_middleware/test_flask_middleware.py +201 -179
  53. tests/test_middleware/test_security_middleware.py +145 -130
  54. tests/test_utils/test_datetime_compat.py +147 -0
  55. mcp_security_framework-1.1.0.dist-info/RECORD +0 -82
  56. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/WHEEL +0 -0
  57. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/entry_points.txt +0 -0
  58. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.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,82 +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=yRLKp9YXQxpdRUqzlJ9xcCW4PnXpBBpSpMeeysrYWPU,38620
8
- mcp_security_framework/core/cert_manager.py,sha256=mPO5LNo6MdYgiY8akEQ-cn58AsQOCvnurOWYYFmC3WY,78659
9
- mcp_security_framework/core/permission_manager.py,sha256=Ts_O_A0AMl_vAcMxRG9LpYbBl3cR6Anv0LAS0rwpKr4,26489
10
- mcp_security_framework/core/rate_limiter.py,sha256=QMdlRRqf-GU7eUgM5vttjvhkYmFs2INX9f0qMgxO8BY,20694
11
- mcp_security_framework/core/security_manager.py,sha256=mwDSFHswp91Wc90PQ9JyIukqq15dO4lK56yjmoY5PDA,38176
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/comprehensive_example.py,sha256=ZEz1lOJM-a2hy8ccMeRdVZzdunGyOPhuYaf59xMWe4E,35738
15
- mcp_security_framework/examples/django_example.py,sha256=RFmZlXj9_fWpIjQrm3z798IQEq4iLZu8NbHg7NNAIbY,24433
16
- mcp_security_framework/examples/fastapi_example.py,sha256=BFJjDCq3kmHowxREvb9Cb2rqzRAJPOo5HzBx1ccGovc,36346
17
- mcp_security_framework/examples/flask_example.py,sha256=6BhplNC9yA-7cBs03J1Amo0sR7V0vP4NFj8LP3Sd9JA,20619
18
- mcp_security_framework/examples/gateway_example.py,sha256=BOEmykUJ56eGilZJT5V1j1swaW62MvlXLrE1aL0l2pw,33279
19
- mcp_security_framework/examples/microservice_example.py,sha256=MUKAqV-0-xLga6VVddgVNfAsapgOgh7RDroWrDhEkvE,29951
20
- mcp_security_framework/examples/standalone_example.py,sha256=IckipYe2I4wzbdmOV2EN1_ycucY-W4fU57ocKEgOtzQ,30633
21
- mcp_security_framework/examples/test_all_examples.py,sha256=BkxHUUL_2hWc2f3b15lnlja3Zwp6frcic9GQVfhaXEY,20074
22
- mcp_security_framework/middleware/__init__.py,sha256=wSBfpfdrz4ErqhwCOJI1uxbQ5Q22_2HdjrxmwwWuj0o,8027
23
- mcp_security_framework/middleware/auth_middleware.py,sha256=kk0koMxrESjJ_nZ_6h5WvuupGA0exK1Q19n0Spuw1k8,10242
24
- mcp_security_framework/middleware/fastapi_auth_middleware.py,sha256=LsCBlU4XRja66VCDkYEHk7fmD27-SrAGyPOijtxmRHQ,17502
25
- mcp_security_framework/middleware/fastapi_middleware.py,sha256=J8olLT3SICbM-NJ2m11cPkOfhREtlJHYk5ENfggbuU4,27260
26
- mcp_security_framework/middleware/flask_auth_middleware.py,sha256=e94Y8SqfPikg0V-tap3iK9TffHqSCKXvclKdBCatLWg,20891
27
- mcp_security_framework/middleware/flask_middleware.py,sha256=wtHafpEgOvA8ZEIzJQzt-LqbIrcFWd1sz8QJXNpgkEU,21083
28
- mcp_security_framework/middleware/mtls_middleware.py,sha256=TsI9BwFkX98KqG9E1bpFFOrcA8vsaumRc0GH6dOEHRs,14694
29
- mcp_security_framework/middleware/rate_limit_middleware.py,sha256=EgjF7mzhkdgfL4nT4eLtKchWmmwaa50WCuIVwYwl_ac,13661
30
- mcp_security_framework/middleware/security_middleware.py,sha256=aQDt9ktMzs0KzNq_aW_23dfOSTmIrWHNj_ps0O7MK40,17804
31
- mcp_security_framework/schemas/__init__.py,sha256=lefkbRlbj2ICfasSj51MQ04o3z1YycnbnknSJCFfXbU,2590
32
- mcp_security_framework/schemas/config.py,sha256=dMlMum-pCWMwYoqBm14dUD725pOW63dYPfIqXv_0maQ,25816
33
- mcp_security_framework/schemas/models.py,sha256=5L-GdtHmuH8HfYkAueeN2Amm6l9i0jIv72jJbDejLlI,26813
34
- mcp_security_framework/schemas/responses.py,sha256=nVXaqF5GTSprXTa_wiUEu38nvSw9WAXtKViAJNbO-Xg,23206
35
- mcp_security_framework/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- mcp_security_framework/utils/__init__.py,sha256=wwwdmQYHTSz0Puvs9FD6aIKmWp3NFARe3JPWNH-b_wk,3098
37
- mcp_security_framework/utils/cert_utils.py,sha256=TzErmDK_dAtDCNDnUPh_Oa13HkUDev-G_pHGSXS3cB4,17160
38
- mcp_security_framework/utils/crypto_utils.py,sha256=OH2V7_C3FjStxFTIXMUPfNXZuWG2-QjgoBrIH4Lv4p0,12392
39
- mcp_security_framework/utils/validation_utils.py,sha256=e9BX3kw9gdXSmFsc7lmG-qnzSlK0-Ynn7Xs4uKHquF4,16279
40
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- tests/conftest.py,sha256=Ws5h-n_hAry_QKquFA0h1TW-v8sHGi2_t06S0s5YOw8,9024
42
- tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- tests/test_cli/test_cert_cli.py,sha256=3hL_4y9-908sjgLrFQVNrm0Pr8yacNCAzKf9avisfDY,14327
44
- tests/test_cli/test_security_cli.py,sha256=oMEUEzt-B-UR-acAzUa-BR1YDOGEwdmKiSy-MIuflGE,25926
45
- tests/test_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
- tests/test_core/test_auth_manager.py,sha256=tyJUe3yBP95SFwbhSr_IloKhEQw0BuEdvjAC1Hnwu4s,22540
47
- tests/test_core/test_cert_manager.py,sha256=MPbrf0qUvRP0Yj67xowuw7gI20HQWgBobGsvFz30iKM,36083
48
- tests/test_core/test_permission_manager.py,sha256=0XeghWXZqVpKyyRuhuDu1dkLUSwuZaFWkRQxQhkkFVI,14966
49
- tests/test_core/test_rate_limiter.py,sha256=YzzlhlxZm-A7YGMiIV8LXDA0zmb_6uRF9GRx9s21Q0U,22544
50
- tests/test_core/test_security_manager.py,sha256=y8klHTMeBoh16wI-10-7gd92T7ZpmuPaSmDtfWM88Ns,35007
51
- tests/test_core/test_ssl_manager.py,sha256=Vm_Nw4SoVro_iwPPc_uD9CwzXpVBkGyVH7EqDtHawvU,20362
52
- tests/test_examples/__init__.py,sha256=VC0N1wB9d01Acnqfos-9x68o23xxHkRhAh4-1qJKUTc,157
53
- tests/test_examples/test_comprehensive_example.py,sha256=JqCa7QKlk0wY0jHm9G22_AkWcuQCTIOOvCoCnWr3ZIA,26142
54
- tests/test_examples/test_fastapi_example.py,sha256=BsWlWdRue7VwluWaj3psaeIlQl7Ra_kBBJqOzsMRMws,13260
55
- tests/test_examples/test_flask_example.py,sha256=nh7As80LDz2vZXhLOo9IaJDNZiYBRdMbItDS_PhihwE,12822
56
- tests/test_examples/test_standalone_example.py,sha256=rw8Djqw9dhgtz2P50y9rBXUWYij30uK-cjdWzJHyamI,8520
57
- tests/test_integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
- tests/test_integration/test_auth_flow.py,sha256=-qtPdfy_uGbcW8wh4K31VlSlFkHiLKYRszg8lC5_o0E,19212
59
- tests/test_integration/test_certificate_flow.py,sha256=ILX7b01Oum5DBYb4UusSzwniqgUkc5bbhLzcPEihjJo,19969
60
- tests/test_integration/test_fastapi_integration.py,sha256=5BhqPSWC07WCgoq4moEx9PX0XLJxOLljGrd25ZwccUs,13401
61
- tests/test_integration/test_flask_integration.py,sha256=hZ3yerzG8n1hrTLKMR0-LuERTYEide_-t_8xyvUSvjY,15767
62
- tests/test_integration/test_standalone_integration.py,sha256=K8n7hkSYEqwCMSxfNC0Iwedr9SA7YJSFXIeoq0kRqLc,19076
63
- tests/test_middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- tests/test_middleware/test_fastapi_auth_middleware.py,sha256=pORcQ1DssYBcO1yEQO402mUFgXRn9QRfkaQKshlm06o,30139
65
- tests/test_middleware/test_fastapi_middleware.py,sha256=43U1PGHDa9a8AnvJpbuyUE1psDuvj2-g64dWkEuqTBM,21150
66
- tests/test_middleware/test_flask_auth_middleware.py,sha256=KP-JvrtZbf67i-g8rkXJmBnay_CppXqTGuDh-ZQu1gM,25356
67
- tests/test_middleware/test_flask_middleware.py,sha256=OfucOhChC3rr8UdSYz2EWQzCtA0oalMqzDxdiT1tNOQ,23364
68
- tests/test_middleware/test_security_middleware.py,sha256=X7Ui-jPkZ2czobEZRf6NwXovH8sGiwYYUdIR7ADQLXA,19653
69
- tests/test_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- tests/test_schemas/test_config.py,sha256=Bp_yZ_HBIl7jcR7Wb1S9iCB0tCu_Ov26YKHTulDs1RU,29430
71
- tests/test_schemas/test_models.py,sha256=bBeZOPqveuVJuEi_BTVWdVsdj08JXJTEFwvBM4eFRVU,34311
72
- tests/test_schemas/test_responses.py,sha256=ZSbO7A3ThPBovTXO8PFF-2ONWAjJx2dMOoV2lQIfd8s,40774
73
- tests/test_schemas/test_serialization.py,sha256=jCugAyrdD6Mw1U7Kxni9oTukarZmMMl6KUcl6cq_NTk,18599
74
- tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
- tests/test_utils/test_cert_utils.py,sha256=2k1kUCJy0T2HPBwOcU5USGfEBQZ_rGzumAGkDdywLak,21232
76
- tests/test_utils/test_crypto_utils.py,sha256=yEb4hzG6-irj2DPoXY0DUboJfbeR87ussgTuBpxLGz4,20737
77
- tests/test_utils/test_validation_utils.py,sha256=lus_wHJ2WyVnBGQ28S7dSv78uWcCIuLhn5uflJw-uGw,18569
78
- mcp_security_framework-1.1.0.dist-info/METADATA,sha256=QZQBtZE8weA0gcd3G0g2Yx2GErDQ-TLqge2_CCmlIf4,11680
79
- mcp_security_framework-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
- mcp_security_framework-1.1.0.dist-info/entry_points.txt,sha256=qBh92fVDmd1m2f3xeW0hTu3Ksg8QfGJyV8UEkdA2itg,142
81
- mcp_security_framework-1.1.0.dist-info/top_level.txt,sha256=ifUiGrTDcD574MXSOoAN2rp2wpUvWlb4jD9LTUgDWCA,29
82
- mcp_security_framework-1.1.0.dist-info/RECORD,,