mcp-proxy-adapter 6.0.0__py3-none-any.whl → 6.0.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.
- mcp_proxy_adapter/__main__.py +27 -7
- mcp_proxy_adapter/api/app.py +209 -79
- mcp_proxy_adapter/api/handlers.py +16 -5
- mcp_proxy_adapter/api/middleware/__init__.py +14 -9
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
- mcp_proxy_adapter/api/middleware/factory.py +36 -12
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +84 -18
- mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
- mcp_proxy_adapter/commands/__init__.py +7 -1
- mcp_proxy_adapter/commands/base.py +7 -4
- mcp_proxy_adapter/commands/builtin_commands.py +8 -2
- mcp_proxy_adapter/commands/command_registry.py +8 -0
- mcp_proxy_adapter/commands/echo_command.py +81 -0
- mcp_proxy_adapter/commands/health_command.py +1 -1
- mcp_proxy_adapter/commands/help_command.py +21 -14
- mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
- mcp_proxy_adapter/commands/role_test_command.py +141 -0
- mcp_proxy_adapter/commands/security_command.py +488 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +234 -351
- mcp_proxy_adapter/commands/token_management_command.py +1 -1
- mcp_proxy_adapter/config.py +323 -40
- mcp_proxy_adapter/core/app_factory.py +410 -0
- mcp_proxy_adapter/core/app_runner.py +272 -0
- mcp_proxy_adapter/core/certificate_utils.py +291 -73
- mcp_proxy_adapter/core/client.py +574 -0
- mcp_proxy_adapter/core/client_manager.py +284 -0
- mcp_proxy_adapter/core/client_security.py +384 -0
- mcp_proxy_adapter/core/logging.py +8 -3
- mcp_proxy_adapter/core/mtls_asgi.py +156 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/protocol_manager.py +169 -10
- mcp_proxy_adapter/core/proxy_client.py +602 -0
- mcp_proxy_adapter/core/proxy_registration.py +299 -47
- mcp_proxy_adapter/core/security_adapter.py +12 -15
- mcp_proxy_adapter/core/security_integration.py +286 -0
- mcp_proxy_adapter/core/server_adapter.py +282 -0
- mcp_proxy_adapter/core/server_engine.py +270 -0
- mcp_proxy_adapter/core/ssl_utils.py +13 -12
- mcp_proxy_adapter/core/transport_manager.py +5 -5
- mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
- mcp_proxy_adapter/examples/__init__.py +13 -4
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +44 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
- mcp_proxy_adapter/examples/debug_request_state.py +112 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
- mcp_proxy_adapter/examples/demo_client.py +275 -0
- mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
- mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
- mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
- mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
- mcp_proxy_adapter/examples/full_application/main.py +173 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
- mcp_proxy_adapter/examples/generate_certificates.py +177 -0
- mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
- mcp_proxy_adapter/examples/run_example.py +59 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
- mcp_proxy_adapter/examples/run_security_tests.py +544 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
- mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
- mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
- mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/security_test_client.py +782 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
- mcp_proxy_adapter/examples/test_config.py +148 -0
- mcp_proxy_adapter/examples/test_config_generator.py +86 -0
- mcp_proxy_adapter/examples/test_examples.py +281 -0
- mcp_proxy_adapter/examples/universal_client.py +620 -0
- mcp_proxy_adapter/main.py +66 -148
- mcp_proxy_adapter/utils/config_generator.py +1008 -0
- mcp_proxy_adapter/version.py +5 -2
- mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
- mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
- mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
- {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
- mcp_proxy_adapter/api/middleware/auth.py +0 -146
- mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
- mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
- mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
- mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
- mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
- mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
- mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
- mcp_proxy_adapter/api/middleware/security.py +0 -376
- mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
- mcp_proxy_adapter/examples/README.md +0 -124
- mcp_proxy_adapter/examples/basic_server/README.md +0 -60
- mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
- mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
- mcp_proxy_adapter/examples/basic_server/config.json +0 -70
- mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
- mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
- mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
- mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
- mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
- mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
- mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
- mcp_proxy_adapter/examples/basic_server/server.py +0 -114
- mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
- mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
- mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
- mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
- mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
- mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
- mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
- mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
- mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
- mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
- mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
- mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
- mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
- mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
- mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
- mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
- mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
- mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
- mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
- mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
- mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
- mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
- mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
- mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
- mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
- mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
- mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
- mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
- mcp_proxy_adapter/examples/deployment/README.md +0 -49
- mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
- mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
- mcp_proxy_adapter/examples/deployment/config.json +0 -29
- mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
- mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
- mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
- mcp_proxy_adapter/examples/deployment/run.sh +0 -43
- mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
- mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
- mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
- mcp_proxy_adapter/schemas/base_schema.json +0 -114
- mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
- mcp_proxy_adapter/schemas/roles_schema.json +0 -162
- mcp_proxy_adapter/tests/__init__.py +0 -0
- mcp_proxy_adapter/tests/api/__init__.py +0 -3
- mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
- mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
- mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
- mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
- mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
- mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
- mcp_proxy_adapter/tests/commands/__init__.py +0 -3
- mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
- mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
- mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
- mcp_proxy_adapter/tests/conftest.py +0 -131
- mcp_proxy_adapter/tests/functional/__init__.py +0 -3
- mcp_proxy_adapter/tests/functional/test_api.py +0 -253
- mcp_proxy_adapter/tests/integration/__init__.py +0 -3
- mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
- mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
- mcp_proxy_adapter/tests/performance/__init__.py +0 -3
- mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
- mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
- mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
- mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
- mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
- mcp_proxy_adapter/tests/test_base_command.py +0 -123
- mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
- mcp_proxy_adapter/tests/test_command_registry.py +0 -281
- mcp_proxy_adapter/tests/test_config.py +0 -127
- mcp_proxy_adapter/tests/test_utils.py +0 -65
- mcp_proxy_adapter/tests/unit/__init__.py +0 -3
- mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
- mcp_proxy_adapter/tests/unit/test_config.py +0 -270
- mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
- mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
- {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
mcp_proxy_adapter/__init__.py,sha256=B7m1YWyv_Wb87-Q-JqVpHQgwajnfIgDyZ_iIxzdTbBY,1021
|
2
|
+
mcp_proxy_adapter/__main__.py,sha256=-Wp1myP9DzJNB9j97mj62C8kFk5YUbCmd0e7Rnwte0A,769
|
3
|
+
mcp_proxy_adapter/config.py,sha256=ss6A-7Ef1I7iyZ-h-bzGWGwddB47642wEhN7uwnt5bk,21563
|
4
|
+
mcp_proxy_adapter/custom_openapi.py,sha256=jYUrCy8C1mShh3sjKj-JkzSMLAvxDLTvtzSJFj5HUNg,15023
|
5
|
+
mcp_proxy_adapter/main.py,sha256=9qt_pEQdq8roUc73CumfDn6jDWP_NyfdE1lCGEynv5I,2841
|
6
|
+
mcp_proxy_adapter/openapi.py,sha256=36vOEbJjGnVZR6hUhl6mHCD29HYOEFKo2bL0JdGSm-4,13952
|
7
|
+
mcp_proxy_adapter/version.py,sha256=he5ZytTjuzxFCrKQ9AxOJw6hhMuKvgK4oyLQ4ErooZQ,76
|
8
|
+
mcp_proxy_adapter/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
mcp_proxy_adapter/api/app.py,sha256=khl4kaI4mJ6dNbfAK7hR97Ek-eWC9NBeuXHr6GVbLoU,28911
|
10
|
+
mcp_proxy_adapter/api/handlers.py,sha256=DcZT7MVBV33q-0EJ0iFqxE0VgBkFt6d_SqoRkntwyvc,8477
|
11
|
+
mcp_proxy_adapter/api/schemas.py,sha256=xOmiSwHaapY6myEFnLu7o-LWVPM7vwmLYZXFo2c6NfE,12381
|
12
|
+
mcp_proxy_adapter/api/tool_integration.py,sha256=MrtX7vUXCGBBuZuOs3C6EF67R_U_0xMfOmlmsAz-wuE,10245
|
13
|
+
mcp_proxy_adapter/api/tools.py,sha256=rRCRN2I8Odd2biBJZKByQS15rAWf0XwLRZEHDELc7Tg,8116
|
14
|
+
mcp_proxy_adapter/api/middleware/__init__.py,sha256=2tkokajbmHLsOS_jKEgOJq-YekyIZahDWcQChMfeKdg,2146
|
15
|
+
mcp_proxy_adapter/api/middleware/base.py,sha256=aMV9YPLHkUnJECuQWYbnlEGaj6xUJFHZR_hJb0OKvu8,2282
|
16
|
+
mcp_proxy_adapter/api/middleware/command_permission_middleware.py,sha256=sSdHTZ-ZxtcV3fJmcweB3sqlQivrYO_FO0H835jnPFA,5076
|
17
|
+
mcp_proxy_adapter/api/middleware/error_handling.py,sha256=avIZTjXj1sNOT3ekKtLAYJKM7V4duX0BF9PW-j18dEY,7134
|
18
|
+
mcp_proxy_adapter/api/middleware/factory.py,sha256=yDo7f4E-YL7qQZgGApyk8HZfLYOnrpsNx-Eh3fJBikE,8404
|
19
|
+
mcp_proxy_adapter/api/middleware/logging.py,sha256=VvUUX7bN4davCzFO6GYbN1O4sgJjOspV-EBLE3xpwpc,4730
|
20
|
+
mcp_proxy_adapter/api/middleware/performance.py,sha256=dHBxTF43LEGXMKHMH3A8ybKmwAWURd_zswqq_oC4xbw,2454
|
21
|
+
mcp_proxy_adapter/api/middleware/protocol_middleware.py,sha256=iVjJrTEfKy15ZchQUo-Mu0hBg9kEP6vgzee_3PtWd6M,8115
|
22
|
+
mcp_proxy_adapter/api/middleware/transport_middleware.py,sha256=Esy2gGKpEV5RoUTilr1YKKTDc5jh5RxsomD0VXyR2pE,4396
|
23
|
+
mcp_proxy_adapter/api/middleware/unified_security.py,sha256=fDWUeIuHjYUngVnB8gVR9ES3IQSaY9VP2YPZGXATJlU,7617
|
24
|
+
mcp_proxy_adapter/api/middleware/user_info_middleware.py,sha256=CWZvwUqieNhC8_ArTvncRjFfU3RHusO-dMcUSvRv01A,6311
|
25
|
+
mcp_proxy_adapter/commands/__init__.py,sha256=r791wg4FKhWSi5rqA3vekDcGf5kr18pwF1woX-dnZKo,1525
|
26
|
+
mcp_proxy_adapter/commands/auth_validation_command.py,sha256=z612WJDVgZwaCrxdQhATwRc5i3qxH37MPuIV6SuZPn8,15083
|
27
|
+
mcp_proxy_adapter/commands/base.py,sha256=tunyrmt-LYJMQZslAZQor3KZvOrn1IYNpL5uOAnSdxc,15791
|
28
|
+
mcp_proxy_adapter/commands/builtin_commands.py,sha256=oloxk0itnY4Uy1a3ARXqHPm48RqkHxBbHqzXZ4bUGN8,3258
|
29
|
+
mcp_proxy_adapter/commands/catalog_manager.py,sha256=FVyF2Ky8DUmvFxjiem3YeC9ASFOzCZ9Lp2MsNobA1wI,34712
|
30
|
+
mcp_proxy_adapter/commands/cert_monitor_command.py,sha256=JWitmmHDeooWXt2fWLbcfAHDeHpsTL2AuBaoka7OWNE,24485
|
31
|
+
mcp_proxy_adapter/commands/certificate_management_command.py,sha256=4byTb1yCqTQCbNH_L4p_z3HithuugzI3a-H9gjiLDhg,24440
|
32
|
+
mcp_proxy_adapter/commands/command_registry.py,sha256=mPNhLnJ4L1lSyVzYXpUjeCBJkWIqEtlzpr9JcprHIf4,35260
|
33
|
+
mcp_proxy_adapter/commands/config_command.py,sha256=-Z6BGaEQTf859l56zZpHYBeZFeIVdpMYybDrd7LOPIg,3553
|
34
|
+
mcp_proxy_adapter/commands/dependency_container.py,sha256=Uz9OPRAUZN7tsVrMVgXgPQcsRD2N-e2Ixg9XarPOlnY,3410
|
35
|
+
mcp_proxy_adapter/commands/dependency_manager.py,sha256=lmY79MBkh-JRIPsYxSkdrUE9XHi4XBCbucaEMT0w6do,7683
|
36
|
+
mcp_proxy_adapter/commands/echo_command.py,sha256=R1oDNEAJSOIuODa4Nk3z4WJXhSxniNzaZtYHADlV310,2390
|
37
|
+
mcp_proxy_adapter/commands/health_command.py,sha256=cNUfvQI4MAJQK1wKfzv_snCCK-FkL-FulVSErkMA3qw,4585
|
38
|
+
mcp_proxy_adapter/commands/help_command.py,sha256=PuanwvYmVs64DhB71gaI5rBRi_ozJ6x8afr18bRpTk4,13482
|
39
|
+
mcp_proxy_adapter/commands/hooks.py,sha256=Gu5TDSgA9EBHexWMWze8wgT63i6-dMEEwG8edWbrX3U,10060
|
40
|
+
mcp_proxy_adapter/commands/key_management_command.py,sha256=qin-iYXksIXOkZEfmJpclJSOyKaz9qRinj9uVa8hkdk,19339
|
41
|
+
mcp_proxy_adapter/commands/load_command.py,sha256=2zwPOCSBck6mr5KehyyH8lPRAqYYGeUeIIJdbxMSoZk,5984
|
42
|
+
mcp_proxy_adapter/commands/plugins_command.py,sha256=Te6YQH0ukJWIHAAEJE5DmdAilpjO1QMDa_PexhfQLH0,8531
|
43
|
+
mcp_proxy_adapter/commands/protocol_management_command.py,sha256=XSrNPGagopM4SinrSmNFW12KLng7-Oc9q6NpiInJ-QI,8485
|
44
|
+
mcp_proxy_adapter/commands/proxy_registration_command.py,sha256=yqPKgpv8oPP9mn1Blo-2VRVoWUpMcMJ29stqy2Di7hk,15394
|
45
|
+
mcp_proxy_adapter/commands/reload_command.py,sha256=6yJduQlIgXhtDSH4Q8qmfR8wZW1RVC1WT1eBIpxzCNo,7507
|
46
|
+
mcp_proxy_adapter/commands/result.py,sha256=9iFyoRRZ17q3d822XTMNyqnBvWypyoyV0NiHtM2bCd4,5604
|
47
|
+
mcp_proxy_adapter/commands/role_test_command.py,sha256=Hr45vB3W8tg_GQ4FfKOEOxW10eEb-pApo2nOPjru61M,4281
|
48
|
+
mcp_proxy_adapter/commands/roles_management_command.py,sha256=JSMkW9-Hq9ncltUvBjolQdvSeTa1FY2hoU0oD2mBon4,22471
|
49
|
+
mcp_proxy_adapter/commands/security_command.py,sha256=zKTVtb8vL_DafRHtrLqC2Mhk_DjOQ-3YwhIUh8NXJfQ,18206
|
50
|
+
mcp_proxy_adapter/commands/settings_command.py,sha256=hTBrFRABJDFYwnDf2ryfqoejUe06fM4XMOoiH0Exdyo,6407
|
51
|
+
mcp_proxy_adapter/commands/ssl_setup_command.py,sha256=wCWF7VhAB21m1FF7uR7r1mG1uLu6bFkfTfpHINM7LGI,13101
|
52
|
+
mcp_proxy_adapter/commands/token_management_command.py,sha256=7sl_fRUjWMRuP7NXoLjpLTB9wEg_aZU9dp5Ji9hbThA,18147
|
53
|
+
mcp_proxy_adapter/commands/transport_management_command.py,sha256=yv2lqUqJliYGIbYW7t0HQTrt5Cu2Y02rUjVzdznLtPk,4692
|
54
|
+
mcp_proxy_adapter/commands/unload_command.py,sha256=mhRZ23sJtTwUfWkjZzH8KDRpwxUX0kdu8LbAXAURRJc,5079
|
55
|
+
mcp_proxy_adapter/core/__init__.py,sha256=Ch50cV5Nd8m-HO9rMnVModajjwDK-OdUy7hxISDFkAM,800
|
56
|
+
mcp_proxy_adapter/core/app_factory.py,sha256=Xwyz40GNOWWa7ThArweawNBY4WI4bEI3_cj251mLHCM,17797
|
57
|
+
mcp_proxy_adapter/core/app_runner.py,sha256=JPpx9rKmaHAVdFnHRl2rXycptQkTSQ13Er7Qf1KZIA4,10614
|
58
|
+
mcp_proxy_adapter/core/auth_validator.py,sha256=lJxBVkoQWSk5CNtnPYMEJSsz4FhcXK-gB5QJ_OP9jEE,20937
|
59
|
+
mcp_proxy_adapter/core/certificate_utils.py,sha256=7VOhjRcygCToYgPTUt_MgcNILdpRBRBNZSFpeS_QrfA,39541
|
60
|
+
mcp_proxy_adapter/core/client.py,sha256=YxtaHvMoqKcjWJ-2mf2FH22wUGWUZjXMEKPqxypNOPE,21340
|
61
|
+
mcp_proxy_adapter/core/client_manager.py,sha256=sKEhapMpogqb54WIWEpz2bMjrX3wvYooX-a844IfCTU,9164
|
62
|
+
mcp_proxy_adapter/core/client_security.py,sha256=8isHpvv-7H85QzI8K3Pfyr_KdvpE2xYyIT4wqWrttNU,13575
|
63
|
+
mcp_proxy_adapter/core/config_converter.py,sha256=FAA2zx-yRgqMgzg73o9Aq5CEEfodNCeaA8Yluto4wAs,16985
|
64
|
+
mcp_proxy_adapter/core/config_validator.py,sha256=qDVmkRatuDeWylIPLjMq02Vpzff6DDTE_CstpzqGi7o,7773
|
65
|
+
mcp_proxy_adapter/core/errors.py,sha256=s34OxiIR4NCJu_pYSigKXqrIvRjUUK2OWw0X4dpDjIA,5151
|
66
|
+
mcp_proxy_adapter/core/logging.py,sha256=jQlFz52Xwapef6UD4p0acmaGFumD9XuexwW4frDN_ZM,9626
|
67
|
+
mcp_proxy_adapter/core/mtls_asgi.py,sha256=X2lAj3wk3L85amRCp_-10sqvZa5wJf_diXhwrrQReSo,5311
|
68
|
+
mcp_proxy_adapter/core/mtls_asgi_app.py,sha256=VeolP08TTaqYU5fGeaZexj6EBWBDugoVrEGXzJW4PuM,6406
|
69
|
+
mcp_proxy_adapter/core/protocol_manager.py,sha256=ISFRXjUuK4Q3uMbVB8-O_ozQSsDEH0PQA_HAKGeUrrw,14763
|
70
|
+
mcp_proxy_adapter/core/proxy_client.py,sha256=shP373Yelz7Fja22U6XnH0kT9XtPtWEFwOFlYFO97gw,22511
|
71
|
+
mcp_proxy_adapter/core/proxy_registration.py,sha256=87ko1vw61nHJGo0-xrObXiyQhrYK2K6nKr8rXID-j8c,19424
|
72
|
+
mcp_proxy_adapter/core/role_utils.py,sha256=wMoTVz3gF5fM7jozNMwsEwPkp1tui26M-t_KH1Oz8gs,12880
|
73
|
+
mcp_proxy_adapter/core/security_adapter.py,sha256=wZ3OH1WzhUdpN8N8CrGJSFFVNi474DqdazIqQ1T8PN4,13343
|
74
|
+
mcp_proxy_adapter/core/security_factory.py,sha256=4r7qvBq30XfosGD_b1ZHyNVLN8rOQ3NAKuaCOCEK8jA,8262
|
75
|
+
mcp_proxy_adapter/core/security_integration.py,sha256=6oJKVCL1CRnk3sTWX-PBzDjv737oe4QL-9r3l89kRkc,13715
|
76
|
+
mcp_proxy_adapter/core/server_adapter.py,sha256=8dhUlLxuYjaoNgMHieFCFgDRjxskP--Y5uoAhbN6RLw,9823
|
77
|
+
mcp_proxy_adapter/core/server_engine.py,sha256=SFENSDrVMlBD--HgKSRVklhrtLKSRSZhs_3UHxFCGbg,9540
|
78
|
+
mcp_proxy_adapter/core/settings.py,sha256=ZfUnmqD1tjAuaQo2VAF8evC1oHUit7gTu4WkTF0IMYI,10628
|
79
|
+
mcp_proxy_adapter/core/ssl_utils.py,sha256=_2mhpuoiRpSbUBifnQvtuziQfBRrXQUKtB58ALWTaqU,8220
|
80
|
+
mcp_proxy_adapter/core/transport_manager.py,sha256=ppcgjO-7Ulrk1ovlzlXVM89Iw4VOGA3awKgLf7FFAJ0,9518
|
81
|
+
mcp_proxy_adapter/core/unified_config_adapter.py,sha256=cpN_VrliIFGDH3JsfRkTlFdQvLcmuMYYedq0QEzlb0Y,22857
|
82
|
+
mcp_proxy_adapter/core/utils.py,sha256=ly8Ttg2v1OBukThJLxudRvmttU1hxJFLJUfat4b2dOI,3268
|
83
|
+
mcp_proxy_adapter/examples/__init__.py,sha256=k1F-EotAFbJ3JvK_rNgiH4bUztmxIWtYn0AfbAZ1ZGs,450
|
84
|
+
mcp_proxy_adapter/examples/create_certificates_simple.py,sha256=KhP-J98e3GRfEsueEtPlACyOVNWVVxRwBZWBMged_YA,25743
|
85
|
+
mcp_proxy_adapter/examples/debug_request_state.py,sha256=x_H3NIlkmIS6lZimvEM6kCXxGdpgFw99Sdui8qa_qeU,4347
|
86
|
+
mcp_proxy_adapter/examples/debug_role_chain.py,sha256=33l2Tk5mrcnwPFwqm2NTHcrWaJrXUU2wxW2I6Y4uIg4,8344
|
87
|
+
mcp_proxy_adapter/examples/demo_client.py,sha256=inic-FP5qG8oQXUaCrtEhmhac_PDZ1pcxp-M1cxSzwA,10240
|
88
|
+
mcp_proxy_adapter/examples/generate_all_certificates.py,sha256=rgcwqIkQ1eDfEIRFRXGIOz-jOSS1w0GPBRhYvMl6Vjc,16948
|
89
|
+
mcp_proxy_adapter/examples/generate_certificates.py,sha256=A34OHUEiFvINOHrm3_JiDSbp-WG-eQXIvKCsE8JAeXQ,6616
|
90
|
+
mcp_proxy_adapter/examples/generate_certificates_and_tokens.py,sha256=J0qHm_BMY8RYqfuwf7V7xKsHcsRJx8E7x-8JxmW5sPw,15988
|
91
|
+
mcp_proxy_adapter/examples/generate_test_configs.py,sha256=NLhPrA9AfPlQ0WCbOJ1B_V9OC445tanKTmq7aAWKULU,13672
|
92
|
+
mcp_proxy_adapter/examples/proxy_registration_example.py,sha256=g59_QG2D1CCqhIXEvgy2XmgXI3toLmLyH7hL3uHZwC8,12647
|
93
|
+
mcp_proxy_adapter/examples/run_example.py,sha256=o8rcy9Xo0UuZG4MpKdex3pFWYdtAi6uW8dEBQE6Yzbw,2539
|
94
|
+
mcp_proxy_adapter/examples/run_full_test_suite.py,sha256=7Z6qDOvbndGPue1P9v-GcYZxy_XPqoC9voJ7tR8eKQ8,12428
|
95
|
+
mcp_proxy_adapter/examples/run_proxy_server.py,sha256=vkEjqREcOSw2elH_VOBLa0cFjL8gCZp9nkRa8YLsndI,5119
|
96
|
+
mcp_proxy_adapter/examples/run_security_tests.py,sha256=BFeafoRXOhorJ8ScjjnlmPdRaCG8AaPAxb-PRnSGJTM,22639
|
97
|
+
mcp_proxy_adapter/examples/run_security_tests_fixed.py,sha256=fNQsbALf9548xJ0OGPKYx5Crzg1GbcL8CSh1x_oKu_A,10540
|
98
|
+
mcp_proxy_adapter/examples/security_test_client.py,sha256=0j0-RGg9kppt_IAuYeT8cbXr3N5gqBdzEyPd3RW0bs8,35558
|
99
|
+
mcp_proxy_adapter/examples/setup_test_environment.py,sha256=fAfz1U7qERY-Z9ly15Wld8Zci-5_e9zSrvYJ56Rjowo,11839
|
100
|
+
mcp_proxy_adapter/examples/test_config.py,sha256=1X9X8lNlWOcM1ZbIzteeMvLdgxnJEK_ev1BYTZiA9ws,6451
|
101
|
+
mcp_proxy_adapter/examples/test_config_generator.py,sha256=SBKL0bv-kUwUUbwrFVbxuA_6pDvK2573Jxm9wPiyI8s,3927
|
102
|
+
mcp_proxy_adapter/examples/test_examples.py,sha256=KH095FFEQDMKYZglclr5qy3cW__t3H8VX1l8dvCkQos,12132
|
103
|
+
mcp_proxy_adapter/examples/universal_client.py,sha256=IIKGRa0__KoWVla3VnVl-RjkkG_nPpM8vglPm70pV9c,26948
|
104
|
+
mcp_proxy_adapter/examples/basic_framework/__init__.py,sha256=4aYD--R6hy9n9CUxj7Osb9HcdVUMJ6_cfpu4ujkbCwI,345
|
105
|
+
mcp_proxy_adapter/examples/basic_framework/main.py,sha256=cDmqeUN1lDBBwuwLjmnP3qIyofCZ3Jr5Ct7Im-qCsUU,1728
|
106
|
+
mcp_proxy_adapter/examples/basic_framework/commands/__init__.py,sha256=_VQNLUEdsxUG-4yt9BZI_vtOxHAdGG0OUSsP6Wj-Vz4,76
|
107
|
+
mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py,sha256=IE_EIXMnkdXuakZn7wLD9kBFyfDF5lYi56ejgiBeb-A,70
|
108
|
+
mcp_proxy_adapter/examples/commands/__init__.py,sha256=46FZSOABSeKPffw91JqIWL_UQD_RLL3nAR-ufgb2hr8,169
|
109
|
+
mcp_proxy_adapter/examples/examples/basic_framework/__init__.py,sha256=4aYD--R6hy9n9CUxj7Osb9HcdVUMJ6_cfpu4ujkbCwI,345
|
110
|
+
mcp_proxy_adapter/examples/examples/basic_framework/main.py,sha256=cDmqeUN1lDBBwuwLjmnP3qIyofCZ3Jr5Ct7Im-qCsUU,1728
|
111
|
+
mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py,sha256=_VQNLUEdsxUG-4yt9BZI_vtOxHAdGG0OUSsP6Wj-Vz4,76
|
112
|
+
mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py,sha256=IE_EIXMnkdXuakZn7wLD9kBFyfDF5lYi56ejgiBeb-A,70
|
113
|
+
mcp_proxy_adapter/examples/examples/full_application/__init__.py,sha256=AEqN_gEBzj-swBtTOvRUWqKSdXqJVk1aUtfPghVL-2o,319
|
114
|
+
mcp_proxy_adapter/examples/examples/full_application/main.py,sha256=h2d90G6XMJFbJpo2ht7M1IqITZ9nZPi9QtH6ETeE9DI,7791
|
115
|
+
mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py,sha256=-cpb0nIjzp6OltFHoZqrtFvb4wJf1dgT4WvQ2dcY6Bo,6045
|
116
|
+
mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py,sha256=yQHxVSFkAyFLUOdk42QOebUODPlQV9IbydPgF3UKsGM,217
|
117
|
+
mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py,sha256=u9_XOkoHkiFC-tn9B-yGUXfQi9OL0EDxlVVKSERI1wA,3099
|
118
|
+
mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py,sha256=fRWtegpUUVt4wWOz3yE3spMG4h1DM_xbSxg_WqlnbF0,3491
|
119
|
+
mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py,sha256=ORG4cL8cSXEMmZ0CEPz75OVuwg54pdDm2GIBpP4dtcs,200
|
120
|
+
mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py,sha256=TYXuHI-KW_mH5r8mSKgNMJCr3moeEKrqC4Eex0U298k,3457
|
121
|
+
mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py,sha256=IaskSrckZS6bE3aGxSBL8aTj-iJTSI2ysfsFjhjncyM,2975
|
122
|
+
mcp_proxy_adapter/examples/full_application/__init__.py,sha256=AEqN_gEBzj-swBtTOvRUWqKSdXqJVk1aUtfPghVL-2o,319
|
123
|
+
mcp_proxy_adapter/examples/full_application/main.py,sha256=h2d90G6XMJFbJpo2ht7M1IqITZ9nZPi9QtH6ETeE9DI,7791
|
124
|
+
mcp_proxy_adapter/examples/full_application/proxy_endpoints.py,sha256=-cpb0nIjzp6OltFHoZqrtFvb4wJf1dgT4WvQ2dcY6Bo,6045
|
125
|
+
mcp_proxy_adapter/examples/full_application/commands/__init__.py,sha256=yQHxVSFkAyFLUOdk42QOebUODPlQV9IbydPgF3UKsGM,217
|
126
|
+
mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py,sha256=u9_XOkoHkiFC-tn9B-yGUXfQi9OL0EDxlVVKSERI1wA,3099
|
127
|
+
mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py,sha256=fRWtegpUUVt4wWOz3yE3spMG4h1DM_xbSxg_WqlnbF0,3491
|
128
|
+
mcp_proxy_adapter/examples/full_application/hooks/__init__.py,sha256=ORG4cL8cSXEMmZ0CEPz75OVuwg54pdDm2GIBpP4dtcs,200
|
129
|
+
mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py,sha256=TYXuHI-KW_mH5r8mSKgNMJCr3moeEKrqC4Eex0U298k,3457
|
130
|
+
mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py,sha256=IaskSrckZS6bE3aGxSBL8aTj-iJTSI2ysfsFjhjncyM,2975
|
131
|
+
mcp_proxy_adapter/examples/scripts/config_generator.py,sha256=4qruYxQ2kGLVOukLX2JOW5kslJ06RhkNqTobAgh4rfw,32801
|
132
|
+
mcp_proxy_adapter/examples/scripts/create_certificates_simple.py,sha256=xkIvUYl6hbKlWImQmenG0k_CvIsOsc9ZHICiKY3rtI8,26380
|
133
|
+
mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py,sha256=J0qHm_BMY8RYqfuwf7V7xKsHcsRJx8E7x-8JxmW5sPw,15988
|
134
|
+
mcp_proxy_adapter/utils/config_generator.py,sha256=2dxwBh9k_nUw9kgytZso5TNOQpBqd3c-RpKSTLoHlLE,46465
|
135
|
+
mcp_proxy_adapter-6.0.1.dist-info/licenses/LICENSE,sha256=6KdtUcTwmTRbJrAmYjVn7e6S-V42ubeDJ-AiVEzZ510,1075
|
136
|
+
mcp_proxy_adapter-6.0.1.dist-info/METADATA,sha256=UYIC4jHUJrNCj-7FlIHqekZvym3C5njJhaPp8XesdXA,22347
|
137
|
+
mcp_proxy_adapter-6.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
138
|
+
mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt,sha256=J3eV6ID0lt_VSp4lIdIgBFTqLCThgObNNxRCbyfiMHw,70
|
139
|
+
mcp_proxy_adapter-6.0.1.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
|
140
|
+
mcp_proxy_adapter-6.0.1.dist-info/RECORD,,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2024 Vasiliy Zdanovskiy
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
21
|
+
SOFTWARE.
|
@@ -1,146 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Middleware for authentication.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import json
|
6
|
-
from typing import Dict, List, Optional, Callable, Awaitable
|
7
|
-
|
8
|
-
from fastapi import Request, Response
|
9
|
-
from starlette.responses import JSONResponse
|
10
|
-
|
11
|
-
from mcp_proxy_adapter.core.logging import logger
|
12
|
-
from .base import BaseMiddleware
|
13
|
-
|
14
|
-
class AuthMiddleware(BaseMiddleware):
|
15
|
-
"""
|
16
|
-
Middleware for authenticating requests.
|
17
|
-
"""
|
18
|
-
|
19
|
-
def __init__(self, app, api_keys: Dict[str, str] = None, public_paths: List[str] = None, auth_enabled: bool = True):
|
20
|
-
"""
|
21
|
-
Initializes middleware for authentication.
|
22
|
-
|
23
|
-
Args:
|
24
|
-
app: FastAPI application
|
25
|
-
api_keys: Dictionary with API keys (key: username)
|
26
|
-
public_paths: List of paths accessible without authentication
|
27
|
-
auth_enabled: Flag to enable/disable authentication
|
28
|
-
"""
|
29
|
-
super().__init__(app)
|
30
|
-
self.api_keys = api_keys or {}
|
31
|
-
self.public_paths = public_paths or [
|
32
|
-
"/docs",
|
33
|
-
"/redoc",
|
34
|
-
"/openapi.json",
|
35
|
-
"/health"
|
36
|
-
]
|
37
|
-
self.auth_enabled = auth_enabled
|
38
|
-
|
39
|
-
async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
|
40
|
-
"""
|
41
|
-
Processes request and checks authentication.
|
42
|
-
|
43
|
-
Args:
|
44
|
-
request: Request.
|
45
|
-
call_next: Next handler.
|
46
|
-
|
47
|
-
Returns:
|
48
|
-
Response.
|
49
|
-
"""
|
50
|
-
# Check if authentication is disabled
|
51
|
-
if not self.auth_enabled:
|
52
|
-
logger.debug("Authentication is disabled, skipping authentication check")
|
53
|
-
return await call_next(request)
|
54
|
-
|
55
|
-
# Check if path is public
|
56
|
-
path = request.url.path
|
57
|
-
if self._is_public_path(path):
|
58
|
-
# If path is public, skip authentication
|
59
|
-
return await call_next(request)
|
60
|
-
|
61
|
-
# Check for API key in header
|
62
|
-
api_key = request.headers.get("X-API-Key")
|
63
|
-
|
64
|
-
if not api_key:
|
65
|
-
# Check for API key in query parameters
|
66
|
-
api_key = request.query_params.get("api_key")
|
67
|
-
|
68
|
-
if not api_key and request.method in ["POST", "PUT", "PATCH"]:
|
69
|
-
# Check for API key in JSON-RPC request body
|
70
|
-
try:
|
71
|
-
body = await request.body()
|
72
|
-
if body:
|
73
|
-
try:
|
74
|
-
body_json = json.loads(body.decode("utf-8"))
|
75
|
-
# Look for API key in params of JSON-RPC object
|
76
|
-
if isinstance(body_json, dict) and "params" in body_json:
|
77
|
-
api_key = body_json.get("params", {}).get("api_key")
|
78
|
-
except json.JSONDecodeError:
|
79
|
-
pass
|
80
|
-
except Exception:
|
81
|
-
pass
|
82
|
-
|
83
|
-
# If API key not found, return error
|
84
|
-
if not api_key:
|
85
|
-
logger.warning(f"Authentication failed: API key not provided | Path: {path}")
|
86
|
-
return self._create_error_response("API key not provided", 401)
|
87
|
-
|
88
|
-
# Check if API key is valid
|
89
|
-
username = self._validate_api_key(api_key)
|
90
|
-
if not username:
|
91
|
-
logger.warning(f"Authentication failed: Invalid API key | Path: {path}")
|
92
|
-
return self._create_error_response("Invalid API key", 401)
|
93
|
-
|
94
|
-
# If API key is valid, save user information in request state
|
95
|
-
request.state.username = username
|
96
|
-
logger.info(f"Authentication successful: {username} | Path: {path}")
|
97
|
-
|
98
|
-
# Call the next middleware or main handler
|
99
|
-
return await call_next(request)
|
100
|
-
|
101
|
-
def _is_public_path(self, path: str) -> bool:
|
102
|
-
"""
|
103
|
-
Checks if the path is public.
|
104
|
-
|
105
|
-
Args:
|
106
|
-
path: Path to check.
|
107
|
-
|
108
|
-
Returns:
|
109
|
-
True if path is public, False otherwise.
|
110
|
-
"""
|
111
|
-
return any(path.startswith(public_path) for public_path in self.public_paths)
|
112
|
-
|
113
|
-
def _validate_api_key(self, api_key: str) -> Optional[str]:
|
114
|
-
"""
|
115
|
-
Validates API key.
|
116
|
-
|
117
|
-
Args:
|
118
|
-
api_key: API key to validate.
|
119
|
-
|
120
|
-
Returns:
|
121
|
-
Username if API key is valid, otherwise None.
|
122
|
-
"""
|
123
|
-
return self.api_keys.get(api_key)
|
124
|
-
|
125
|
-
def _create_error_response(self, message: str, status_code: int) -> Response:
|
126
|
-
"""
|
127
|
-
Creates error response in JSON-RPC format.
|
128
|
-
|
129
|
-
Args:
|
130
|
-
message: Error message.
|
131
|
-
status_code: HTTP status code.
|
132
|
-
|
133
|
-
Returns:
|
134
|
-
JSON response with error.
|
135
|
-
"""
|
136
|
-
return JSONResponse(
|
137
|
-
status_code=status_code,
|
138
|
-
content={
|
139
|
-
"jsonrpc": "2.0",
|
140
|
-
"error": {
|
141
|
-
"code": -32000,
|
142
|
-
"message": message
|
143
|
-
},
|
144
|
-
"id": None
|
145
|
-
}
|
146
|
-
)
|
@@ -1,235 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Auth Middleware Adapter for backward compatibility.
|
3
|
-
|
4
|
-
This module provides an adapter that maintains the same interface as AuthMiddleware
|
5
|
-
while using the new SecurityMiddleware internally.
|
6
|
-
"""
|
7
|
-
|
8
|
-
import json
|
9
|
-
from typing import Dict, List, Optional, Callable, Awaitable
|
10
|
-
|
11
|
-
from fastapi import Request, Response
|
12
|
-
from starlette.responses import JSONResponse
|
13
|
-
|
14
|
-
from mcp_proxy_adapter.core.logging import logger
|
15
|
-
from .base import BaseMiddleware
|
16
|
-
from .security import SecurityMiddleware
|
17
|
-
|
18
|
-
|
19
|
-
class AuthMiddlewareAdapter(BaseMiddleware):
|
20
|
-
"""
|
21
|
-
Adapter for AuthMiddleware that uses SecurityMiddleware internally.
|
22
|
-
|
23
|
-
Maintains the same interface as the original AuthMiddleware for backward compatibility.
|
24
|
-
"""
|
25
|
-
|
26
|
-
def __init__(self, app, api_keys: Dict[str, str] = None,
|
27
|
-
public_paths: List[str] = None, auth_enabled: bool = True):
|
28
|
-
"""
|
29
|
-
Initialize auth middleware adapter.
|
30
|
-
|
31
|
-
Args:
|
32
|
-
app: FastAPI application
|
33
|
-
api_keys: Dictionary with API keys (key: username)
|
34
|
-
public_paths: List of paths accessible without authentication
|
35
|
-
auth_enabled: Flag to enable/disable authentication
|
36
|
-
"""
|
37
|
-
super().__init__(app)
|
38
|
-
|
39
|
-
# Store original parameters for backward compatibility
|
40
|
-
self.api_keys = api_keys or {}
|
41
|
-
self.public_paths = public_paths or [
|
42
|
-
"/docs",
|
43
|
-
"/redoc",
|
44
|
-
"/openapi.json",
|
45
|
-
"/health"
|
46
|
-
]
|
47
|
-
self.auth_enabled = auth_enabled
|
48
|
-
|
49
|
-
# Create internal security middleware
|
50
|
-
self.security_middleware = self._create_security_middleware()
|
51
|
-
|
52
|
-
logger.info(f"AuthMiddlewareAdapter initialized: auth_enabled={auth_enabled}, "
|
53
|
-
f"api_keys_count={len(self.api_keys)}, public_paths_count={len(self.public_paths)}")
|
54
|
-
|
55
|
-
def _create_security_middleware(self) -> SecurityMiddleware:
|
56
|
-
"""
|
57
|
-
Create internal SecurityMiddleware with AuthMiddleware configuration.
|
58
|
-
|
59
|
-
Returns:
|
60
|
-
SecurityMiddleware instance
|
61
|
-
"""
|
62
|
-
# Convert AuthMiddleware config to SecurityMiddleware config
|
63
|
-
security_config = {
|
64
|
-
"security": {
|
65
|
-
"enabled": self.auth_enabled,
|
66
|
-
"auth": {
|
67
|
-
"enabled": self.auth_enabled,
|
68
|
-
"methods": ["api_key"],
|
69
|
-
"api_keys": self.api_keys
|
70
|
-
},
|
71
|
-
"ssl": {
|
72
|
-
"enabled": False
|
73
|
-
},
|
74
|
-
"permissions": {
|
75
|
-
"enabled": False
|
76
|
-
},
|
77
|
-
"rate_limit": {
|
78
|
-
"enabled": False
|
79
|
-
},
|
80
|
-
"public_paths": self.public_paths
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
return SecurityMiddleware(self.app, security_config)
|
85
|
-
|
86
|
-
async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
|
87
|
-
"""
|
88
|
-
Process request using internal SecurityMiddleware with legacy API key handling.
|
89
|
-
|
90
|
-
Args:
|
91
|
-
request: Request object
|
92
|
-
call_next: Next handler
|
93
|
-
|
94
|
-
Returns:
|
95
|
-
Response object
|
96
|
-
"""
|
97
|
-
# Check if authentication is disabled
|
98
|
-
if not self.auth_enabled:
|
99
|
-
logger.debug("Authentication is disabled, skipping authentication check")
|
100
|
-
return await call_next(request)
|
101
|
-
|
102
|
-
# Check if path is public
|
103
|
-
path = request.url.path
|
104
|
-
if self._is_public_path(path):
|
105
|
-
return await call_next(request)
|
106
|
-
|
107
|
-
# Extract API key from various sources (legacy compatibility)
|
108
|
-
api_key = self._extract_api_key(request)
|
109
|
-
|
110
|
-
# Check for API key in JSON-RPC request body if not found in headers/query
|
111
|
-
if not api_key and request.method in ["POST", "PUT", "PATCH"]:
|
112
|
-
try:
|
113
|
-
body = await request.body()
|
114
|
-
if body:
|
115
|
-
try:
|
116
|
-
body_json = json.loads(body.decode("utf-8"))
|
117
|
-
# Look for API key in params of JSON-RPC object
|
118
|
-
if isinstance(body_json, dict) and "params" in body_json:
|
119
|
-
api_key = body_json.get("params", {}).get("api_key")
|
120
|
-
except json.JSONDecodeError:
|
121
|
-
pass
|
122
|
-
except Exception:
|
123
|
-
pass
|
124
|
-
|
125
|
-
if api_key:
|
126
|
-
# Validate API key
|
127
|
-
username = self._validate_api_key(api_key)
|
128
|
-
if username:
|
129
|
-
# Store username in request state for backward compatibility
|
130
|
-
request.state.username = username
|
131
|
-
logger.debug(f"API key authentication successful for {username}")
|
132
|
-
return await call_next(request)
|
133
|
-
else:
|
134
|
-
logger.warning(f"Invalid API key provided | Path: {path}")
|
135
|
-
return self._create_error_response("Invalid API key", 401)
|
136
|
-
else:
|
137
|
-
logger.warning(f"API key not provided | Path: {path}")
|
138
|
-
return self._create_error_response("API key not provided", 401)
|
139
|
-
|
140
|
-
def _extract_api_key(self, request: Request) -> Optional[str]:
|
141
|
-
"""
|
142
|
-
Extract API key from request (legacy compatibility).
|
143
|
-
|
144
|
-
Args:
|
145
|
-
request: Request object
|
146
|
-
|
147
|
-
Returns:
|
148
|
-
API key or None
|
149
|
-
"""
|
150
|
-
# Check for API key in header
|
151
|
-
api_key = request.headers.get("X-API-Key")
|
152
|
-
|
153
|
-
if not api_key:
|
154
|
-
# Check for API key in query parameters
|
155
|
-
api_key = request.query_params.get("api_key")
|
156
|
-
|
157
|
-
# Note: Body extraction is handled in dispatch method
|
158
|
-
# This method only handles headers and query parameters
|
159
|
-
|
160
|
-
return api_key
|
161
|
-
|
162
|
-
def _is_public_path(self, path: str) -> bool:
|
163
|
-
"""
|
164
|
-
Check if the path is public (doesn't require authentication).
|
165
|
-
|
166
|
-
Args:
|
167
|
-
path: Request path
|
168
|
-
|
169
|
-
Returns:
|
170
|
-
True if path is public, False otherwise
|
171
|
-
"""
|
172
|
-
return any(path.startswith(public_path) for public_path in self.public_paths)
|
173
|
-
|
174
|
-
def _validate_api_key(self, api_key: str) -> Optional[str]:
|
175
|
-
"""
|
176
|
-
Validate API key and return username.
|
177
|
-
|
178
|
-
Args:
|
179
|
-
api_key: API key to validate
|
180
|
-
|
181
|
-
Returns:
|
182
|
-
Username if valid, None otherwise
|
183
|
-
"""
|
184
|
-
return self.api_keys.get(api_key)
|
185
|
-
|
186
|
-
def _create_error_response(self, message: str, status_code: int) -> JSONResponse:
|
187
|
-
"""
|
188
|
-
Create error response in AuthMiddleware format.
|
189
|
-
|
190
|
-
Args:
|
191
|
-
message: Error message
|
192
|
-
status_code: HTTP status code
|
193
|
-
|
194
|
-
Returns:
|
195
|
-
JSONResponse with error
|
196
|
-
"""
|
197
|
-
return JSONResponse(
|
198
|
-
status_code=status_code,
|
199
|
-
content={
|
200
|
-
"jsonrpc": "2.0",
|
201
|
-
"error": {
|
202
|
-
"code": -32000 if status_code == 401 else -32603,
|
203
|
-
"message": message,
|
204
|
-
"data": {
|
205
|
-
"auth_type": "api_key",
|
206
|
-
"status_code": status_code
|
207
|
-
}
|
208
|
-
},
|
209
|
-
"id": None
|
210
|
-
}
|
211
|
-
)
|
212
|
-
|
213
|
-
def get_username(self, request: Request) -> Optional[str]:
|
214
|
-
"""
|
215
|
-
Get username from request state (backward compatibility).
|
216
|
-
|
217
|
-
Args:
|
218
|
-
request: Request object
|
219
|
-
|
220
|
-
Returns:
|
221
|
-
Username or None
|
222
|
-
"""
|
223
|
-
return getattr(request.state, 'username', None)
|
224
|
-
|
225
|
-
def is_authenticated(self, request: Request) -> bool:
|
226
|
-
"""
|
227
|
-
Check if request is authenticated (backward compatibility).
|
228
|
-
|
229
|
-
Args:
|
230
|
-
request: Request object
|
231
|
-
|
232
|
-
Returns:
|
233
|
-
True if authenticated, False otherwise
|
234
|
-
"""
|
235
|
-
return hasattr(request.state, 'username') and request.state.username is not None
|