mcp-proxy-adapter 4.1.1__py3-none-any.whl → 6.1.0__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 (253) hide show
  1. mcp_proxy_adapter/__main__.py +12 -0
  2. mcp_proxy_adapter/api/app.py +254 -33
  3. mcp_proxy_adapter/api/handlers.py +32 -6
  4. mcp_proxy_adapter/api/middleware/__init__.py +36 -30
  5. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  6. mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
  7. mcp_proxy_adapter/api/middleware/factory.py +243 -0
  8. mcp_proxy_adapter/api/middleware/logging.py +32 -6
  9. mcp_proxy_adapter/api/middleware/protocol_middleware.py +135 -0
  10. mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
  11. mcp_proxy_adapter/api/middleware/unified_security.py +152 -0
  12. mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
  13. mcp_proxy_adapter/commands/__init__.py +19 -4
  14. mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
  15. mcp_proxy_adapter/commands/base.py +66 -32
  16. mcp_proxy_adapter/commands/builtin_commands.py +95 -0
  17. mcp_proxy_adapter/commands/catalog_manager.py +838 -0
  18. mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
  19. mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
  20. mcp_proxy_adapter/commands/command_registry.py +711 -354
  21. mcp_proxy_adapter/commands/dependency_manager.py +245 -0
  22. mcp_proxy_adapter/commands/echo_command.py +81 -0
  23. mcp_proxy_adapter/commands/health_command.py +7 -0
  24. mcp_proxy_adapter/commands/help_command.py +21 -14
  25. mcp_proxy_adapter/commands/hooks.py +200 -167
  26. mcp_proxy_adapter/commands/key_management_command.py +506 -0
  27. mcp_proxy_adapter/commands/load_command.py +176 -0
  28. mcp_proxy_adapter/commands/plugins_command.py +235 -0
  29. mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
  30. mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
  31. mcp_proxy_adapter/commands/reload_command.py +48 -50
  32. mcp_proxy_adapter/commands/result.py +1 -0
  33. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  34. mcp_proxy_adapter/commands/roles_management_command.py +697 -0
  35. mcp_proxy_adapter/commands/security_command.py +488 -0
  36. mcp_proxy_adapter/commands/ssl_setup_command.py +483 -0
  37. mcp_proxy_adapter/commands/token_management_command.py +529 -0
  38. mcp_proxy_adapter/commands/transport_management_command.py +144 -0
  39. mcp_proxy_adapter/commands/unload_command.py +158 -0
  40. mcp_proxy_adapter/config.py +159 -2
  41. mcp_proxy_adapter/core/app_factory.py +326 -0
  42. mcp_proxy_adapter/core/auth_validator.py +606 -0
  43. mcp_proxy_adapter/core/certificate_utils.py +827 -0
  44. mcp_proxy_adapter/core/client_security.py +384 -0
  45. mcp_proxy_adapter/core/config_converter.py +405 -0
  46. mcp_proxy_adapter/core/config_validator.py +218 -0
  47. mcp_proxy_adapter/core/logging.py +19 -3
  48. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  49. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  50. mcp_proxy_adapter/core/protocol_manager.py +235 -0
  51. mcp_proxy_adapter/core/proxy_client.py +602 -0
  52. mcp_proxy_adapter/core/proxy_registration.py +522 -0
  53. mcp_proxy_adapter/core/role_utils.py +426 -0
  54. mcp_proxy_adapter/core/security_adapter.py +370 -0
  55. mcp_proxy_adapter/core/security_factory.py +239 -0
  56. mcp_proxy_adapter/core/security_integration.py +277 -0
  57. mcp_proxy_adapter/core/server_adapter.py +345 -0
  58. mcp_proxy_adapter/core/server_engine.py +364 -0
  59. mcp_proxy_adapter/core/settings.py +1 -0
  60. mcp_proxy_adapter/core/ssl_utils.py +233 -0
  61. mcp_proxy_adapter/core/transport_manager.py +292 -0
  62. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  63. mcp_proxy_adapter/custom_openapi.py +22 -11
  64. mcp_proxy_adapter/examples/README.md +230 -97
  65. mcp_proxy_adapter/examples/README_EN.md +258 -0
  66. mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
  67. mcp_proxy_adapter/examples/__pycache__/security_configurations.cpython-312.pyc +0 -0
  68. mcp_proxy_adapter/examples/__pycache__/security_test_client.cpython-312.pyc +0 -0
  69. mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
  70. mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
  71. mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +39 -0
  72. mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +25 -0
  73. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
  74. mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
  75. mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
  76. mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
  77. mcp_proxy_adapter/examples/cert_config.json +9 -0
  78. mcp_proxy_adapter/examples/certs/admin.crt +32 -0
  79. mcp_proxy_adapter/examples/certs/admin.key +52 -0
  80. mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
  81. mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
  82. mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
  83. mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
  84. mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
  85. mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
  86. mcp_proxy_adapter/examples/certs/client.crt +32 -0
  87. mcp_proxy_adapter/examples/certs/client.key +52 -0
  88. mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
  89. mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
  90. mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
  91. mcp_proxy_adapter/examples/certs/client_user.key +52 -0
  92. mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
  93. mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
  94. mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
  95. mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
  96. mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
  97. mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
  98. mcp_proxy_adapter/examples/certs/readonly.key +52 -0
  99. mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
  100. mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
  101. mcp_proxy_adapter/examples/certs/server.crt +32 -0
  102. mcp_proxy_adapter/examples/certs/server.key +52 -0
  103. mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
  104. mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
  105. mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
  106. mcp_proxy_adapter/examples/certs/user.crt +32 -0
  107. mcp_proxy_adapter/examples/certs/user.key +52 -0
  108. mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
  109. mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
  110. mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
  111. mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
  112. mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
  113. mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
  114. mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
  115. mcp_proxy_adapter/examples/commands/__init__.py +1 -0
  116. mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
  117. mcp_proxy_adapter/examples/debug_request_state.py +144 -0
  118. mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
  119. mcp_proxy_adapter/examples/demo_client.py +341 -0
  120. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
  121. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
  122. mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
  123. mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
  124. mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
  125. mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
  126. mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
  127. mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
  128. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
  129. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
  130. mcp_proxy_adapter/examples/full_application/main.py +138 -0
  131. mcp_proxy_adapter/examples/full_application/roles.json +21 -0
  132. mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
  133. mcp_proxy_adapter/examples/generate_certificates.py +121 -0
  134. mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
  135. mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
  136. mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
  137. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
  138. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
  139. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
  140. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
  141. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
  142. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
  143. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
  144. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
  145. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
  146. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
  147. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
  148. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
  149. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
  150. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
  151. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
  152. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
  153. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
  154. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
  155. mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
  156. mcp_proxy_adapter/examples/roles.json +38 -0
  157. mcp_proxy_adapter/examples/run_example.py +81 -0
  158. mcp_proxy_adapter/examples/run_security_tests.py +326 -0
  159. mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
  160. mcp_proxy_adapter/examples/security_test_client.py +743 -0
  161. mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
  162. mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
  163. mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
  164. mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
  165. mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
  166. mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
  167. mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
  168. mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
  169. mcp_proxy_adapter/examples/test_examples.py +344 -0
  170. mcp_proxy_adapter/examples/universal_client.py +628 -0
  171. mcp_proxy_adapter/main.py +186 -0
  172. mcp_proxy_adapter/utils/config_generator.py +639 -0
  173. mcp_proxy_adapter/version.py +2 -1
  174. mcp_proxy_adapter-6.1.0.dist-info/METADATA +205 -0
  175. mcp_proxy_adapter-6.1.0.dist-info/RECORD +193 -0
  176. mcp_proxy_adapter-6.1.0.dist-info/entry_points.txt +2 -0
  177. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/licenses/LICENSE +2 -2
  178. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  179. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  180. mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
  181. mcp_proxy_adapter/examples/__init__.py +0 -7
  182. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  183. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  184. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  185. mcp_proxy_adapter/examples/basic_server/config.json +0 -35
  186. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  187. mcp_proxy_adapter/examples/basic_server/server.py +0 -103
  188. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  189. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  190. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -250
  191. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  192. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  193. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  194. mcp_proxy_adapter/examples/custom_commands/config.json +0 -35
  195. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  196. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  197. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  198. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  199. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  200. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  201. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  202. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  203. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  204. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  205. mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
  206. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  207. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  208. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  209. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  210. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  211. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  212. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  213. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  214. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  215. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  216. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  217. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  218. mcp_proxy_adapter/tests/__init__.py +0 -0
  219. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  220. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  221. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  222. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  223. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  224. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  225. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  226. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  227. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  228. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  229. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  230. mcp_proxy_adapter/tests/conftest.py +0 -131
  231. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  232. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  233. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  234. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  235. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  236. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  237. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  238. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  239. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  240. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  241. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  242. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  243. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  244. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  245. mcp_proxy_adapter/tests/test_config.py +0 -127
  246. mcp_proxy_adapter/tests/test_utils.py +0 -65
  247. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  248. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  249. mcp_proxy_adapter/tests/unit/test_config.py +0 -217
  250. mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
  251. mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
  252. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/WHEEL +0 -0
  253. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,122 @@
1
+ """
2
+ Transport Middleware Module
3
+
4
+ This module provides middleware for transport validation in the MCP Proxy Adapter.
5
+ """
6
+
7
+ from typing import Callable
8
+ from fastapi import Request, Response
9
+ from fastapi.responses import JSONResponse
10
+ from starlette.middleware.base import BaseHTTPMiddleware
11
+
12
+ from mcp_proxy_adapter.core.transport_manager import transport_manager
13
+ from mcp_proxy_adapter.core.logging import logger
14
+
15
+
16
+ class TransportMiddleware(BaseHTTPMiddleware):
17
+ """Middleware for transport validation."""
18
+
19
+ def __init__(self, app, transport_manager_instance=None):
20
+ """
21
+ Initialize transport middleware.
22
+
23
+ Args:
24
+ app: FastAPI application
25
+ transport_manager_instance: Transport manager instance (optional)
26
+ """
27
+ super().__init__(app)
28
+ self.transport_manager = transport_manager_instance or transport_manager
29
+
30
+ async def dispatch(self, request: Request, call_next: Callable) -> Response:
31
+ """
32
+ Process request through transport middleware.
33
+
34
+ Args:
35
+ request: Incoming request
36
+ call_next: Next middleware/endpoint
37
+
38
+ Returns:
39
+ Response from next middleware/endpoint or error response
40
+ """
41
+ # Determine transport type from request
42
+ transport_type = self._get_request_transport_type(request)
43
+
44
+ # Check if request matches configured transport
45
+ if not self._is_transport_allowed(transport_type):
46
+ configured_type = self.transport_manager.get_transport_type()
47
+ configured_type_str = configured_type.value if configured_type else "not configured"
48
+ logger.warning(f"Transport not allowed: {transport_type} for {request.url}")
49
+ return JSONResponse(
50
+ status_code=403,
51
+ content={
52
+ "error": "Transport not allowed",
53
+ "message": f"Transport '{transport_type}' is not allowed. Configured transport: {configured_type_str}",
54
+ "configured_transport": configured_type_str,
55
+ "request_url": str(request.url)
56
+ }
57
+ )
58
+
59
+ # Add transport info to request state
60
+ request.state.transport_type = transport_type
61
+ request.state.transport_allowed = True
62
+
63
+ response = await call_next(request)
64
+ return response
65
+
66
+ def _get_request_transport_type(self, request: Request) -> str:
67
+ """
68
+ Determine transport type from request.
69
+
70
+ Args:
71
+ request: Incoming request
72
+
73
+ Returns:
74
+ Transport type string
75
+ """
76
+ if request.url.scheme == "https":
77
+ # Check for client certificate for MTLS
78
+ if self._has_client_certificate(request):
79
+ return "mtls"
80
+ return "https"
81
+ return "http"
82
+
83
+ def _has_client_certificate(self, request: Request) -> bool:
84
+ """
85
+ Check if request has client certificate.
86
+
87
+ Args:
88
+ request: Incoming request
89
+
90
+ Returns:
91
+ True if client certificate is present, False otherwise
92
+ """
93
+ # Check for client certificate in request headers or SSL context
94
+ # This is a simplified check - in production, you might need more sophisticated detection
95
+ client_cert_header = request.headers.get("ssl-client-cert")
96
+ if client_cert_header:
97
+ return True
98
+
99
+ # Check if request has SSL client certificate context
100
+ if hasattr(request, "client") and request.client:
101
+ # In a real implementation, you would check the SSL context
102
+ # For now, we'll assume HTTPS with client cert is MTLS
103
+ return self.transport_manager.is_mtls()
104
+
105
+ return False
106
+
107
+ def _is_transport_allowed(self, transport_type: str) -> bool:
108
+ """
109
+ Check if transport type is allowed.
110
+
111
+ Args:
112
+ transport_type: Transport type to check
113
+
114
+ Returns:
115
+ True if transport is allowed, False otherwise
116
+ """
117
+ configured_type = self.transport_manager.get_transport_type()
118
+ if not configured_type:
119
+ logger.error("Transport not configured")
120
+ return False
121
+
122
+ return transport_type == configured_type.value
@@ -0,0 +1,152 @@
1
+ """
2
+ Unified Security Middleware - Direct Framework Integration
3
+
4
+ This middleware now directly uses mcp_security_framework components
5
+ instead of custom implementations.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import time
12
+ import logging
13
+ from typing import Dict, Any, Optional, Callable, Awaitable
14
+ from fastapi import Request, Response
15
+ from starlette.middleware.base import BaseHTTPMiddleware
16
+
17
+ # Direct import from framework
18
+ try:
19
+ from mcp_security_framework.middleware.fastapi_middleware import FastAPISecurityMiddleware
20
+ from mcp_security_framework import SecurityManager
21
+ from mcp_security_framework.schemas.config import SecurityConfig
22
+ SECURITY_FRAMEWORK_AVAILABLE = True
23
+ except ImportError:
24
+ SECURITY_FRAMEWORK_AVAILABLE = False
25
+ FastAPISecurityMiddleware = None
26
+ SecurityManager = None
27
+ SecurityConfig = None
28
+
29
+ from mcp_proxy_adapter.core.logging import logger
30
+ from mcp_proxy_adapter.core.security_integration import create_security_integration
31
+
32
+
33
+ class SecurityValidationError(Exception):
34
+ """Security validation error."""
35
+
36
+ def __init__(self, message: str, error_code: int):
37
+ self.message = message
38
+ self.error_code = error_code
39
+ super().__init__(self.message)
40
+
41
+
42
+ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
43
+ """
44
+ Unified security middleware using mcp_security_framework.
45
+
46
+ This middleware now directly uses the security framework's FastAPI middleware
47
+ and components instead of custom implementations.
48
+ """
49
+
50
+ def __init__(self, app, config: Dict[str, Any]):
51
+ """
52
+ Initialize unified security middleware.
53
+
54
+ Args:
55
+ app: FastAPI application
56
+ config: mcp_proxy_adapter configuration dictionary
57
+ """
58
+ super().__init__(app)
59
+ self.config = config
60
+
61
+ # Create security integration
62
+ try:
63
+ self.security_integration = create_security_integration(config)
64
+ # Use framework's FastAPI middleware
65
+ self.framework_middleware = self.security_integration.create_fastapi_middleware(app)
66
+ logger.info("Using mcp_security_framework FastAPI middleware")
67
+ except Exception as e:
68
+ logger.error(f"Security framework integration failed: {e}")
69
+ raise RuntimeError("Security framework integration failed - framework must be available for production use") from e
70
+
71
+ logger.info("Unified security middleware initialized with mcp_security_framework")
72
+
73
+ async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
74
+ """
75
+ Process request using framework middleware.
76
+
77
+ Args:
78
+ request: Request object
79
+ call_next: Next handler
80
+
81
+ Returns:
82
+ Response object
83
+ """
84
+ try:
85
+ # Use framework middleware only
86
+ return await self.framework_middleware.dispatch(request, call_next)
87
+
88
+ except SecurityValidationError as e:
89
+ # Handle security validation errors
90
+ return await self._handle_security_error(request, e)
91
+ except Exception as e:
92
+ # Handle other errors
93
+ logger.error(f"Unexpected error in unified security middleware: {e}")
94
+ return await self._handle_general_error(request, e)
95
+
96
+
97
+
98
+ async def _handle_security_error(self, request: Request, error: SecurityValidationError) -> Response:
99
+ """
100
+ Handle security validation errors.
101
+
102
+ Args:
103
+ request: Request object
104
+ error: Security validation error
105
+
106
+ Returns:
107
+ Error response
108
+ """
109
+ from fastapi.responses import JSONResponse
110
+
111
+ error_response = {
112
+ "error": {
113
+ "code": error.error_code,
114
+ "message": error.message,
115
+ "type": "security_validation_error"
116
+ }
117
+ }
118
+
119
+ logger.warning(f"Security validation failed: {error.message}")
120
+
121
+ return JSONResponse(
122
+ status_code=error.error_code,
123
+ content=error_response
124
+ )
125
+
126
+ async def _handle_general_error(self, request: Request, error: Exception) -> Response:
127
+ """
128
+ Handle general errors.
129
+
130
+ Args:
131
+ request: Request object
132
+ error: General error
133
+
134
+ Returns:
135
+ Error response
136
+ """
137
+ from fastapi.responses import JSONResponse
138
+
139
+ error_response = {
140
+ "error": {
141
+ "code": 500,
142
+ "message": "Internal server error",
143
+ "type": "general_error"
144
+ }
145
+ }
146
+
147
+ logger.error(f"General error in security middleware: {error}")
148
+
149
+ return JSONResponse(
150
+ status_code=500,
151
+ content=error_response
152
+ )
@@ -0,0 +1,83 @@
1
+ """
2
+ User Info Middleware
3
+
4
+ This middleware extracts user information from authentication headers
5
+ and sets it in request.state for use by commands.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import logging
12
+ from typing import Dict, Any, Optional, Callable, Awaitable
13
+ from fastapi import Request, Response
14
+ from starlette.middleware.base import BaseHTTPMiddleware
15
+
16
+ from mcp_proxy_adapter.core.logging import logger
17
+
18
+
19
+ class UserInfoMiddleware(BaseHTTPMiddleware):
20
+ """
21
+ Middleware for setting user information in request.state.
22
+
23
+ This middleware extracts user information from authentication headers
24
+ and sets it in request.state for use by commands.
25
+ """
26
+
27
+ def __init__(self, app, config: Dict[str, Any]):
28
+ """
29
+ Initialize user info middleware.
30
+
31
+ Args:
32
+ app: FastAPI application
33
+ config: Configuration dictionary
34
+ """
35
+ super().__init__(app)
36
+ self.config = config
37
+
38
+ # Get API keys configuration
39
+ security_config = config.get("security", {})
40
+ auth_config = security_config.get("auth", {})
41
+ self.api_keys = auth_config.get("api_keys", {})
42
+
43
+ logger.info("User info middleware initialized")
44
+
45
+ async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
46
+ """
47
+ Process request and set user info in request.state.
48
+
49
+ Args:
50
+ request: Request object
51
+ call_next: Next handler
52
+
53
+ Returns:
54
+ Response object
55
+ """
56
+ # Extract API key from headers
57
+ api_key = request.headers.get("X-API-Key")
58
+
59
+ if api_key and api_key in self.api_keys:
60
+ # Get user info from API key configuration
61
+ user_config = self.api_keys[api_key]
62
+
63
+ # Set user info in request.state
64
+ request.state.user = {
65
+ "id": api_key,
66
+ "role": user_config.get("roles", ["guest"])[0] if user_config.get("roles") else "guest",
67
+ "roles": user_config.get("roles", ["guest"]),
68
+ "permissions": user_config.get("permissions", ["read"])
69
+ }
70
+
71
+ logger.debug(f"Set user info for {api_key}: {request.state.user}")
72
+ else:
73
+ # Set default guest user info
74
+ request.state.user = {
75
+ "id": None,
76
+ "role": "guest",
77
+ "roles": ["guest"],
78
+ "permissions": ["read"]
79
+ }
80
+
81
+ logger.debug("Set default guest user info")
82
+
83
+ return await call_next(request)
@@ -6,9 +6,15 @@ from mcp_proxy_adapter.commands.base import Command
6
6
  from mcp_proxy_adapter.commands.command_registry import registry, CommandRegistry
7
7
  from mcp_proxy_adapter.commands.dependency_container import container, DependencyContainer
8
8
  from mcp_proxy_adapter.commands.result import CommandResult, SuccessResult, ErrorResult
9
-
10
- # Automatically discover and register commands
11
- registry.discover_commands()
9
+ from mcp_proxy_adapter.commands.auth_validation_command import AuthValidationCommand
10
+ from mcp_proxy_adapter.commands.ssl_setup_command import SSLSetupCommand
11
+ from mcp_proxy_adapter.commands.certificate_management_command import CertificateManagementCommand
12
+ from mcp_proxy_adapter.commands.key_management_command import KeyManagementCommand
13
+ from mcp_proxy_adapter.commands.cert_monitor_command import CertMonitorCommand
14
+ from mcp_proxy_adapter.commands.transport_management_command import TransportManagementCommand
15
+ from mcp_proxy_adapter.commands.role_test_command import RoleTestCommand
16
+ from mcp_proxy_adapter.commands.echo_command import EchoCommand
17
+ from mcp_proxy_adapter.commands.proxy_registration_command import ProxyRegistrationCommand
12
18
 
13
19
  __all__ = [
14
20
  "Command",
@@ -18,5 +24,14 @@ __all__ = [
18
24
  "registry",
19
25
  "CommandRegistry",
20
26
  "container",
21
- "DependencyContainer"
27
+ "DependencyContainer",
28
+ "AuthValidationCommand",
29
+ "SSLSetupCommand",
30
+ "CertificateManagementCommand",
31
+ "KeyManagementCommand",
32
+ "CertMonitorCommand",
33
+ "TransportManagementCommand",
34
+ "RoleTestCommand",
35
+ "EchoCommand",
36
+ "ProxyRegistrationCommand"
22
37
  ]