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.
- mcp_proxy_adapter/__main__.py +12 -0
- mcp_proxy_adapter/api/app.py +254 -33
- mcp_proxy_adapter/api/handlers.py +32 -6
- mcp_proxy_adapter/api/middleware/__init__.py +36 -30
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
- mcp_proxy_adapter/api/middleware/factory.py +243 -0
- mcp_proxy_adapter/api/middleware/logging.py +32 -6
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +135 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +152 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
- mcp_proxy_adapter/commands/__init__.py +19 -4
- mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
- mcp_proxy_adapter/commands/base.py +66 -32
- mcp_proxy_adapter/commands/builtin_commands.py +95 -0
- mcp_proxy_adapter/commands/catalog_manager.py +838 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
- mcp_proxy_adapter/commands/command_registry.py +711 -354
- mcp_proxy_adapter/commands/dependency_manager.py +245 -0
- mcp_proxy_adapter/commands/echo_command.py +81 -0
- mcp_proxy_adapter/commands/health_command.py +7 -0
- mcp_proxy_adapter/commands/help_command.py +21 -14
- mcp_proxy_adapter/commands/hooks.py +200 -167
- mcp_proxy_adapter/commands/key_management_command.py +506 -0
- mcp_proxy_adapter/commands/load_command.py +176 -0
- mcp_proxy_adapter/commands/plugins_command.py +235 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
- mcp_proxy_adapter/commands/reload_command.py +48 -50
- mcp_proxy_adapter/commands/result.py +1 -0
- mcp_proxy_adapter/commands/role_test_command.py +141 -0
- mcp_proxy_adapter/commands/roles_management_command.py +697 -0
- mcp_proxy_adapter/commands/security_command.py +488 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +483 -0
- mcp_proxy_adapter/commands/token_management_command.py +529 -0
- mcp_proxy_adapter/commands/transport_management_command.py +144 -0
- mcp_proxy_adapter/commands/unload_command.py +158 -0
- mcp_proxy_adapter/config.py +159 -2
- mcp_proxy_adapter/core/app_factory.py +326 -0
- mcp_proxy_adapter/core/auth_validator.py +606 -0
- mcp_proxy_adapter/core/certificate_utils.py +827 -0
- mcp_proxy_adapter/core/client_security.py +384 -0
- mcp_proxy_adapter/core/config_converter.py +405 -0
- mcp_proxy_adapter/core/config_validator.py +218 -0
- mcp_proxy_adapter/core/logging.py +19 -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 +235 -0
- mcp_proxy_adapter/core/proxy_client.py +602 -0
- mcp_proxy_adapter/core/proxy_registration.py +522 -0
- mcp_proxy_adapter/core/role_utils.py +426 -0
- mcp_proxy_adapter/core/security_adapter.py +370 -0
- mcp_proxy_adapter/core/security_factory.py +239 -0
- mcp_proxy_adapter/core/security_integration.py +277 -0
- mcp_proxy_adapter/core/server_adapter.py +345 -0
- mcp_proxy_adapter/core/server_engine.py +364 -0
- mcp_proxy_adapter/core/settings.py +1 -0
- mcp_proxy_adapter/core/ssl_utils.py +233 -0
- mcp_proxy_adapter/core/transport_manager.py +292 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
- mcp_proxy_adapter/custom_openapi.py +22 -11
- mcp_proxy_adapter/examples/README.md +230 -97
- mcp_proxy_adapter/examples/README_EN.md +258 -0
- mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
- mcp_proxy_adapter/examples/__pycache__/security_configurations.cpython-312.pyc +0 -0
- mcp_proxy_adapter/examples/__pycache__/security_test_client.cpython-312.pyc +0 -0
- mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
- mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
- mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +39 -0
- mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +25 -0
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
- mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
- mcp_proxy_adapter/examples/cert_config.json +9 -0
- mcp_proxy_adapter/examples/certs/admin.crt +32 -0
- mcp_proxy_adapter/examples/certs/admin.key +52 -0
- mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
- mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
- mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
- mcp_proxy_adapter/examples/certs/client.crt +32 -0
- mcp_proxy_adapter/examples/certs/client.key +52 -0
- mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
- mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
- mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
- mcp_proxy_adapter/examples/certs/client_user.key +52 -0
- mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
- mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
- mcp_proxy_adapter/examples/certs/readonly.key +52 -0
- mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/server.crt +32 -0
- mcp_proxy_adapter/examples/certs/server.key +52 -0
- mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
- mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
- mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
- mcp_proxy_adapter/examples/certs/user.crt +32 -0
- mcp_proxy_adapter/examples/certs/user.key +52 -0
- mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
- mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
- mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
- mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
- mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
- mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
- mcp_proxy_adapter/examples/commands/__init__.py +1 -0
- mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
- mcp_proxy_adapter/examples/debug_request_state.py +144 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
- mcp_proxy_adapter/examples/demo_client.py +341 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
- mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
- mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
- mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
- mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
- mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
- mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
- mcp_proxy_adapter/examples/full_application/main.py +138 -0
- mcp_proxy_adapter/examples/full_application/roles.json +21 -0
- mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
- mcp_proxy_adapter/examples/generate_certificates.py +121 -0
- mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
- mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
- mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
- mcp_proxy_adapter/examples/roles.json +38 -0
- mcp_proxy_adapter/examples/run_example.py +81 -0
- mcp_proxy_adapter/examples/run_security_tests.py +326 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
- mcp_proxy_adapter/examples/security_test_client.py +743 -0
- mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
- mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
- mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
- mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
- mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
- mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
- mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
- mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
- mcp_proxy_adapter/examples/test_examples.py +344 -0
- mcp_proxy_adapter/examples/universal_client.py +628 -0
- mcp_proxy_adapter/main.py +186 -0
- mcp_proxy_adapter/utils/config_generator.py +639 -0
- mcp_proxy_adapter/version.py +2 -1
- mcp_proxy_adapter-6.1.0.dist-info/METADATA +205 -0
- mcp_proxy_adapter-6.1.0.dist-info/RECORD +193 -0
- mcp_proxy_adapter-6.1.0.dist-info/entry_points.txt +2 -0
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/licenses/LICENSE +2 -2
- mcp_proxy_adapter/api/middleware/auth.py +0 -146
- mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
- mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
- mcp_proxy_adapter/examples/__init__.py +0 -7
- 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 -35
- mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
- mcp_proxy_adapter/examples/basic_server/server.py +0 -103
- 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 -250
- 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/config.json +0 -35
- 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/hooks.py +0 -230
- mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
- mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
- mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
- 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/schemas/base_schema.json +0 -114
- mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
- 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 -217
- mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
- mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/WHEEL +0 -0
- {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
|
-
|
11
|
-
|
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
|
]
|