mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__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.
Potentially problematic release.
This version of mcp-proxy-adapter might be problematic. Click here for more details.
- mcp_proxy_adapter/__init__.py +47 -0
- mcp_proxy_adapter/__main__.py +13 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +66 -0
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +400 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_context.py +356 -0
- mcp_proxy_adapter/api/core/registration_manager.py +307 -0
- mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +181 -0
- mcp_proxy_adapter/api/middleware/__init__.py +21 -0
- mcp_proxy_adapter/api/middleware/base.py +54 -0
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
- mcp_proxy_adapter/api/middleware/factory.py +147 -0
- mcp_proxy_adapter/api/middleware/logging.py +31 -0
- mcp_proxy_adapter/api/middleware/performance.py +51 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
- mcp_proxy_adapter/api/openapi/__init__.py +21 -0
- mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
- mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
- mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
- mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
- mcp_proxy_adapter/api/schemas.py +270 -0
- mcp_proxy_adapter/api/tool_integration.py +131 -0
- mcp_proxy_adapter/api/tools.py +163 -0
- mcp_proxy_adapter/cli/__init__.py +12 -0
- mcp_proxy_adapter/cli/commands/__init__.py +15 -0
- mcp_proxy_adapter/cli/commands/client.py +100 -0
- mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
- mcp_proxy_adapter/cli/commands/generate.py +259 -0
- mcp_proxy_adapter/cli/commands/server.py +174 -0
- mcp_proxy_adapter/cli/commands/sets.py +132 -0
- mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
- mcp_proxy_adapter/cli/examples/__init__.py +8 -0
- mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
- mcp_proxy_adapter/cli/examples/https_token.py +96 -0
- mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
- mcp_proxy_adapter/cli/main.py +63 -0
- mcp_proxy_adapter/cli/parser.py +338 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
- mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
- mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
- mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
- mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
- mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
- mcp_proxy_adapter/client/proxy.py +123 -0
- mcp_proxy_adapter/commands/__init__.py +66 -0
- mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
- mcp_proxy_adapter/commands/base.py +389 -0
- mcp_proxy_adapter/commands/builtin_commands.py +30 -0
- mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
- mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
- mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
- mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
- mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
- mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
- mcp_proxy_adapter/commands/catalog_manager.py +97 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
- mcp_proxy_adapter/commands/command_registry.py +298 -0
- mcp_proxy_adapter/commands/config_command.py +102 -0
- mcp_proxy_adapter/commands/dependency_container.py +40 -0
- mcp_proxy_adapter/commands/dependency_manager.py +143 -0
- mcp_proxy_adapter/commands/echo_command.py +48 -0
- mcp_proxy_adapter/commands/health_command.py +142 -0
- mcp_proxy_adapter/commands/help_command.py +175 -0
- mcp_proxy_adapter/commands/hooks.py +172 -0
- mcp_proxy_adapter/commands/key_management_command.py +484 -0
- mcp_proxy_adapter/commands/load_command.py +123 -0
- mcp_proxy_adapter/commands/plugins_command.py +246 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +76 -0
- mcp_proxy_adapter/commands/registry/__init__.py +18 -0
- mcp_proxy_adapter/commands/registry/command_info.py +103 -0
- mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
- mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
- mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
- mcp_proxy_adapter/commands/reload_command.py +136 -0
- mcp_proxy_adapter/commands/result.py +157 -0
- mcp_proxy_adapter/commands/role_test_command.py +99 -0
- mcp_proxy_adapter/commands/roles_management_command.py +502 -0
- mcp_proxy_adapter/commands/security_command.py +472 -0
- mcp_proxy_adapter/commands/settings_command.py +113 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
- mcp_proxy_adapter/commands/token_management_command.py +500 -0
- mcp_proxy_adapter/commands/transport_management_command.py +129 -0
- mcp_proxy_adapter/commands/unload_command.py +92 -0
- mcp_proxy_adapter/config.py +32 -0
- mcp_proxy_adapter/core/__init__.py +8 -0
- mcp_proxy_adapter/core/app_factory.py +560 -0
- mcp_proxy_adapter/core/app_runner.py +318 -0
- mcp_proxy_adapter/core/auth_validator.py +508 -0
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
- mcp_proxy_adapter/core/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/client.py +608 -0
- mcp_proxy_adapter/core/client_manager.py +271 -0
- mcp_proxy_adapter/core/client_security.py +411 -0
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +237 -0
- mcp_proxy_adapter/core/config/config_factory.py +22 -0
- mcp_proxy_adapter/core/config/config_loader.py +66 -0
- mcp_proxy_adapter/core/config/feature_manager.py +31 -0
- mcp_proxy_adapter/core/config/simple_config.py +204 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
- mcp_proxy_adapter/core/config_converter.py +252 -0
- mcp_proxy_adapter/core/config_validator.py +211 -0
- mcp_proxy_adapter/core/crl_utils.py +362 -0
- mcp_proxy_adapter/core/errors.py +276 -0
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +250 -0
- mcp_proxy_adapter/core/mtls_asgi.py +140 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/mtls_proxy.py +229 -0
- mcp_proxy_adapter/core/mtls_server.py +154 -0
- mcp_proxy_adapter/core/protocol_manager.py +232 -0
- mcp_proxy_adapter/core/proxy/__init__.py +19 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +184 -0
- mcp_proxy_adapter/core/proxy_registration.py +80 -0
- mcp_proxy_adapter/core/role_utils.py +103 -0
- mcp_proxy_adapter/core/security_adapter.py +343 -0
- mcp_proxy_adapter/core/security_factory.py +96 -0
- mcp_proxy_adapter/core/security_integration.py +342 -0
- mcp_proxy_adapter/core/server_adapter.py +251 -0
- mcp_proxy_adapter/core/server_engine.py +217 -0
- mcp_proxy_adapter/core/settings.py +260 -0
- mcp_proxy_adapter/core/signal_handler.py +107 -0
- mcp_proxy_adapter/core/ssl_utils.py +161 -0
- mcp_proxy_adapter/core/transport_manager.py +153 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
- mcp_proxy_adapter/core/utils.py +101 -0
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +219 -0
- mcp_proxy_adapter/core/validation/file_validator.py +131 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
- mcp_proxy_adapter/core/validation/security_validator.py +140 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +58 -0
- mcp_proxy_adapter/examples/__init__.py +16 -0
- 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 +52 -0
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter/examples/check_config.py +413 -0
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/config_builder.py +234 -0
- mcp_proxy_adapter/examples/config_cli.py +282 -0
- mcp_proxy_adapter/examples/create_test_configs.py +174 -0
- mcp_proxy_adapter/examples/debug_request_state.py +130 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
- mcp_proxy_adapter/examples/demo_client.py +287 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
- mcp_proxy_adapter/examples/full_application/main.py +311 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
- mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
- mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
- mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
- mcp_proxy_adapter/examples/generate_config.py +502 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
- mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
- mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
- mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
- mcp_proxy_adapter/examples/queue_server_example.py +85 -0
- mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
- mcp_proxy_adapter/examples/required_certificates.py +208 -0
- mcp_proxy_adapter/examples/run_example.py +77 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
- mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
- mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
- mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
- mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
- mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
- mcp_proxy_adapter/examples/security_test_client.py +72 -0
- mcp_proxy_adapter/examples/setup/__init__.py +24 -0
- mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
- mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
- mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
- mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
- mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
- mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
- mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
- mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
- mcp_proxy_adapter/examples/test_config.py +205 -0
- mcp_proxy_adapter/examples/test_config_builder.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +308 -0
- mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
- mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
- mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
- mcp_proxy_adapter/examples/universal_client.py +674 -0
- mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +311 -0
- mcp_proxy_adapter/openapi.py +375 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/schemas/roles.json +37 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/version.py +5 -0
- mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
- mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
- {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
- mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
- mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
- adapters/__init__.py +0 -16
- analyzers/__init__.py +0 -14
- analyzers/docstring_analyzer.py +0 -199
- analyzers/type_analyzer.py +0 -151
- cli/__init__.py +0 -12
- cli/__main__.py +0 -79
- cli/command_runner.py +0 -233
- dispatchers/__init__.py +0 -14
- dispatchers/base_dispatcher.py +0 -85
- dispatchers/json_rpc_dispatcher.py +0 -198
- generators/__init__.py +0 -14
- generators/endpoint_generator.py +0 -172
- generators/openapi_generator.py +0 -254
- generators/rest_api_generator.py +0 -207
- mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
- mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
- mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
- mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
- openapi_schema/__init__.py +0 -38
- openapi_schema/command_registry.py +0 -312
- openapi_schema/rest_schema.py +0 -510
- openapi_schema/rpc_generator.py +0 -307
- openapi_schema/rpc_schema.py +0 -416
- validators/__init__.py +0 -14
- validators/base_validator.py +0 -23
- validators/docstring_validator.py +0 -75
- validators/metadata_validator.py +0 -76
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Main security test client for comprehensive testing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from aiohttp import ClientSession, ClientTimeout, TCPConnector
|
|
12
|
+
|
|
13
|
+
from .test_result import TestResult
|
|
14
|
+
from .ssl_context_manager import SSLContextManager
|
|
15
|
+
from .auth_manager import AuthManager
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SecurityTestClient:
|
|
19
|
+
"""Security test client for comprehensive testing."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, base_url: str = "http://localhost:8000"):
|
|
22
|
+
"""
|
|
23
|
+
Initialize security test client.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
base_url: Base URL for the server
|
|
27
|
+
"""
|
|
28
|
+
self.base_url = base_url
|
|
29
|
+
self.session: Optional[ClientSession] = None
|
|
30
|
+
self.test_results: List[TestResult] = []
|
|
31
|
+
|
|
32
|
+
# Initialize managers
|
|
33
|
+
project_root = Path(__file__).parent.parent.parent.parent
|
|
34
|
+
self.ssl_manager = SSLContextManager(project_root)
|
|
35
|
+
self.auth_manager = AuthManager()
|
|
36
|
+
|
|
37
|
+
async def __aenter__(self):
|
|
38
|
+
"""Async context manager entry."""
|
|
39
|
+
timeout = ClientTimeout(total=30)
|
|
40
|
+
# Create SSL context only for HTTPS URLs
|
|
41
|
+
if self.base_url.startswith('https://'):
|
|
42
|
+
# Check if this is mTLS (ports 20006, 20007, 20008 are mTLS test ports)
|
|
43
|
+
if any(port in self.base_url for port in ['20006', '20007', '20008']):
|
|
44
|
+
# Use mTLS context with client certificates
|
|
45
|
+
ssl_context = self.ssl_manager.create_ssl_context_for_mtls()
|
|
46
|
+
else:
|
|
47
|
+
# Use regular HTTPS context
|
|
48
|
+
ssl_context = self.ssl_manager.create_ssl_context()
|
|
49
|
+
connector = TCPConnector(ssl=ssl_context)
|
|
50
|
+
else:
|
|
51
|
+
# For HTTP URLs, use default connector without SSL
|
|
52
|
+
connector = TCPConnector()
|
|
53
|
+
|
|
54
|
+
# Create session
|
|
55
|
+
self.session = ClientSession(timeout=timeout, connector=connector)
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
59
|
+
"""Async context manager exit."""
|
|
60
|
+
if self.session:
|
|
61
|
+
await self.session.close()
|
|
62
|
+
|
|
63
|
+
async def test_health_check(
|
|
64
|
+
self, server_url: str, auth_type: str = "none", **kwargs
|
|
65
|
+
) -> TestResult:
|
|
66
|
+
"""Test health check endpoint."""
|
|
67
|
+
start_time = time.time()
|
|
68
|
+
test_name = f"Health Check ({auth_type})"
|
|
69
|
+
try:
|
|
70
|
+
headers = self.auth_manager.create_auth_headers(auth_type, **kwargs)
|
|
71
|
+
async with self.session.get(
|
|
72
|
+
f"{server_url}/health", headers=headers
|
|
73
|
+
) as response:
|
|
74
|
+
duration = time.time() - start_time
|
|
75
|
+
if response.status == 200:
|
|
76
|
+
data = await response.json()
|
|
77
|
+
return TestResult(
|
|
78
|
+
test_name=test_name,
|
|
79
|
+
server_url=server_url,
|
|
80
|
+
auth_type=auth_type,
|
|
81
|
+
success=True,
|
|
82
|
+
status_code=response.status,
|
|
83
|
+
response_data=data,
|
|
84
|
+
duration=duration
|
|
85
|
+
)
|
|
86
|
+
else:
|
|
87
|
+
error_text = await response.text()
|
|
88
|
+
return TestResult(
|
|
89
|
+
test_name=test_name,
|
|
90
|
+
server_url=server_url,
|
|
91
|
+
auth_type=auth_type,
|
|
92
|
+
success=False,
|
|
93
|
+
status_code=response.status,
|
|
94
|
+
error_message=f"HTTP {response.status}: {error_text}",
|
|
95
|
+
duration=duration
|
|
96
|
+
)
|
|
97
|
+
except Exception as e:
|
|
98
|
+
duration = time.time() - start_time
|
|
99
|
+
return TestResult(
|
|
100
|
+
test_name=test_name,
|
|
101
|
+
server_url=server_url,
|
|
102
|
+
auth_type=auth_type,
|
|
103
|
+
success=False,
|
|
104
|
+
error_message=str(e),
|
|
105
|
+
duration=duration
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
async def test_echo_command(
|
|
109
|
+
self, server_url: str, auth_type: str = "none", **kwargs
|
|
110
|
+
) -> TestResult:
|
|
111
|
+
"""Test echo command endpoint."""
|
|
112
|
+
start_time = time.time()
|
|
113
|
+
test_name = f"Echo Command ({auth_type})"
|
|
114
|
+
try:
|
|
115
|
+
headers = self.auth_manager.create_auth_headers(auth_type, **kwargs)
|
|
116
|
+
payload = {
|
|
117
|
+
"jsonrpc": "2.0",
|
|
118
|
+
"method": "echo",
|
|
119
|
+
"params": {"message": "Hello from security test client"},
|
|
120
|
+
"id": 1
|
|
121
|
+
}
|
|
122
|
+
async with self.session.post(
|
|
123
|
+
f"{server_url}/api/jsonrpc", json=payload, headers=headers
|
|
124
|
+
) as response:
|
|
125
|
+
duration = time.time() - start_time
|
|
126
|
+
if response.status == 200:
|
|
127
|
+
data = await response.json()
|
|
128
|
+
return TestResult(
|
|
129
|
+
test_name=test_name,
|
|
130
|
+
server_url=server_url,
|
|
131
|
+
auth_type=auth_type,
|
|
132
|
+
success=True,
|
|
133
|
+
status_code=response.status,
|
|
134
|
+
response_data=data,
|
|
135
|
+
duration=duration
|
|
136
|
+
)
|
|
137
|
+
else:
|
|
138
|
+
error_text = await response.text()
|
|
139
|
+
return TestResult(
|
|
140
|
+
test_name=test_name,
|
|
141
|
+
server_url=server_url,
|
|
142
|
+
auth_type=auth_type,
|
|
143
|
+
success=False,
|
|
144
|
+
status_code=response.status,
|
|
145
|
+
error_message=f"HTTP {response.status}: {error_text}",
|
|
146
|
+
duration=duration
|
|
147
|
+
)
|
|
148
|
+
except Exception as e:
|
|
149
|
+
duration = time.time() - start_time
|
|
150
|
+
return TestResult(
|
|
151
|
+
test_name=test_name,
|
|
152
|
+
server_url=server_url,
|
|
153
|
+
auth_type=auth_type,
|
|
154
|
+
success=False,
|
|
155
|
+
error_message=str(e),
|
|
156
|
+
duration=duration
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Test result data class for security testing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Dict, Optional
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class TestResult:
|
|
14
|
+
"""Test result data class."""
|
|
15
|
+
test_name: str
|
|
16
|
+
server_url: str
|
|
17
|
+
auth_type: str
|
|
18
|
+
success: bool
|
|
19
|
+
status_code: Optional[int] = None
|
|
20
|
+
response_data: Optional[Dict] = None
|
|
21
|
+
error_message: Optional[str] = None
|
|
22
|
+
duration: float = 0.0
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Security Test Client for MCP Proxy Adapter
|
|
4
|
+
This client tests various security configurations including:
|
|
5
|
+
- Basic HTTP
|
|
6
|
+
- HTTP + Token authentication
|
|
7
|
+
- HTTPS
|
|
8
|
+
- HTTPS + Token authentication
|
|
9
|
+
- mTLS with certificate authentication
|
|
10
|
+
|
|
11
|
+
Author: Vasiliy Zdanovskiy
|
|
12
|
+
email: vasilyvz@gmail.com
|
|
13
|
+
"""
|
|
14
|
+
import asyncio
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
# Add project root to path for imports
|
|
19
|
+
current_dir = Path(__file__).parent
|
|
20
|
+
parent_dir = current_dir.parent
|
|
21
|
+
if parent_dir.exists():
|
|
22
|
+
sys.path.insert(0, str(parent_dir))
|
|
23
|
+
sys.path.insert(0, str(current_dir))
|
|
24
|
+
|
|
25
|
+
# Import mcp_security_framework components
|
|
26
|
+
try:
|
|
27
|
+
_MCP_SECURITY_AVAILABLE = True
|
|
28
|
+
print("✅ mcp_security_framework available")
|
|
29
|
+
except ImportError as e:
|
|
30
|
+
print(f"❌ CRITICAL ERROR: mcp_security_framework is required but not available!")
|
|
31
|
+
print(f"❌ Import error: {e}")
|
|
32
|
+
print("❌ Please install mcp_security_framework: pip install mcp_security_framework")
|
|
33
|
+
raise ImportError("mcp_security_framework is required for security tests") from e
|
|
34
|
+
|
|
35
|
+
# Import cryptography components
|
|
36
|
+
try:
|
|
37
|
+
_CRYPTOGRAPHY_AVAILABLE = True
|
|
38
|
+
print("✅ cryptography available")
|
|
39
|
+
except ImportError:
|
|
40
|
+
_CRYPTOGRAPHY_AVAILABLE = False
|
|
41
|
+
print("⚠️ cryptography not available, SSL validation will be limited")
|
|
42
|
+
|
|
43
|
+
# Import security test components
|
|
44
|
+
from .security_test import SecurityTestClient
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def main():
|
|
48
|
+
"""Main function to run security tests."""
|
|
49
|
+
print("🚀 Starting MCP Proxy Adapter Security Tests")
|
|
50
|
+
print("=" * 50)
|
|
51
|
+
|
|
52
|
+
# Define test servers
|
|
53
|
+
test_servers = [
|
|
54
|
+
"http://localhost:8080", # HTTP Basic
|
|
55
|
+
"http://localhost:8080", # HTTP + Token
|
|
56
|
+
"https://localhost:8443", # HTTPS Basic
|
|
57
|
+
"https://localhost:8443", # HTTPS + Token
|
|
58
|
+
"https://localhost:20006", # mTLS Basic
|
|
59
|
+
"https://localhost:20007", # mTLS + Token
|
|
60
|
+
"https://localhost:20008", # mTLS + Roles
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
# Run security tests
|
|
64
|
+
async with SecurityTestClient() as client:
|
|
65
|
+
results = await client.run_security_tests(test_servers)
|
|
66
|
+
client.print_summary()
|
|
67
|
+
|
|
68
|
+
print("\\n🎉 Security tests completed!")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == "__main__":
|
|
72
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Test environment setup package for MCP Proxy Adapter.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .config_validator import ConfigurationValidator
|
|
9
|
+
from .test_files_generator import create_test_files
|
|
10
|
+
from .config_generator import create_configuration_documentation, generate_enhanced_configurations
|
|
11
|
+
from .certificate_manager import generate_certificates_with_framework
|
|
12
|
+
from .test_runner import test_proxy_registration, run_full_test_suite
|
|
13
|
+
from .environment_setup import setup_test_environment
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ConfigurationValidator",
|
|
17
|
+
"create_test_files",
|
|
18
|
+
"create_configuration_documentation",
|
|
19
|
+
"generate_enhanced_configurations",
|
|
20
|
+
"generate_certificates_with_framework",
|
|
21
|
+
"test_proxy_registration",
|
|
22
|
+
"run_full_test_suite",
|
|
23
|
+
"setup_test_environment",
|
|
24
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Certificate manager for MCP Proxy Adapter test environment setup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import subprocess
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import bool
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def generate_certificates_with_framework(output_dir: Path) -> bool:
|
|
15
|
+
"""
|
|
16
|
+
Generate certificates using mcp_security_framework if available.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
output_dir: Directory to generate certificates in
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
True if certificates were generated successfully, False otherwise
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
from mcp_security_framework.core.cert_manager import CertificateManager
|
|
26
|
+
CertificateConfig,
|
|
27
|
+
CAConfig,
|
|
28
|
+
ServerCertConfig,
|
|
29
|
+
ClientCertConfig,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
print("🔐 Generating certificates using mcp_security_framework...")
|
|
33
|
+
|
|
34
|
+
# Create certificate directories
|
|
35
|
+
certs_dir = output_dir / "certs"
|
|
36
|
+
keys_dir = output_dir / "keys"
|
|
37
|
+
certs_dir.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
keys_dir.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
|
|
40
|
+
# Initialize certificate manager
|
|
41
|
+
cert_manager = CertificateManager()
|
|
42
|
+
|
|
43
|
+
# Generate CA certificate
|
|
44
|
+
ca_config = CAConfig(
|
|
45
|
+
common_name="MCP Test CA",
|
|
46
|
+
country="US",
|
|
47
|
+
state="Test State",
|
|
48
|
+
city="Test City",
|
|
49
|
+
organization="MCP Test Org",
|
|
50
|
+
organizational_unit="Test Unit",
|
|
51
|
+
validity_days=365
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
ca_cert_path = certs_dir / "ca_cert.pem"
|
|
55
|
+
ca_key_path = keys_dir / "ca_key.pem"
|
|
56
|
+
|
|
57
|
+
print("📜 Generating CA certificate...")
|
|
58
|
+
cert_manager.generate_ca_certificate(
|
|
59
|
+
ca_config,
|
|
60
|
+
str(ca_cert_path),
|
|
61
|
+
str(ca_key_path)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Generate server certificate
|
|
65
|
+
server_config = ServerCertConfig(
|
|
66
|
+
common_name="localhost",
|
|
67
|
+
san_dns=["localhost", "127.0.0.1"],
|
|
68
|
+
san_ip=["127.0.0.1", "::1"],
|
|
69
|
+
validity_days=365
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
server_cert_path = certs_dir / "localhost_server.crt"
|
|
73
|
+
server_key_path = keys_dir / "server_key.pem"
|
|
74
|
+
|
|
75
|
+
print("🖥️ Generating server certificate...")
|
|
76
|
+
cert_manager.generate_server_certificate(
|
|
77
|
+
server_config,
|
|
78
|
+
str(server_cert_path),
|
|
79
|
+
str(server_key_path),
|
|
80
|
+
str(ca_cert_path),
|
|
81
|
+
str(ca_key_path)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Generate client certificate
|
|
85
|
+
client_config = ClientCertConfig(
|
|
86
|
+
common_name="test-client",
|
|
87
|
+
validity_days=365
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
client_cert_path = certs_dir / "client_cert.pem"
|
|
91
|
+
client_key_path = keys_dir / "client_key.pem"
|
|
92
|
+
|
|
93
|
+
print("👤 Generating client certificate...")
|
|
94
|
+
cert_manager.generate_client_certificate(
|
|
95
|
+
client_config,
|
|
96
|
+
str(client_cert_path),
|
|
97
|
+
str(client_key_path),
|
|
98
|
+
str(ca_cert_path),
|
|
99
|
+
str(ca_key_path)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
print("✅ Certificates generated successfully!")
|
|
103
|
+
print(f" CA Certificate: {ca_cert_path}")
|
|
104
|
+
print(f" Server Certificate: {server_cert_path}")
|
|
105
|
+
print(f" Client Certificate: {client_cert_path}")
|
|
106
|
+
|
|
107
|
+
return True
|
|
108
|
+
|
|
109
|
+
except ImportError:
|
|
110
|
+
print("⚠️ mcp_security_framework not available, using OpenSSL fallback...")
|
|
111
|
+
return _generate_certificates_with_openssl(output_dir)
|
|
112
|
+
except Exception as e:
|
|
113
|
+
print(f"❌ Error generating certificates with framework: {e}")
|
|
114
|
+
print("🔄 Falling back to OpenSSL...")
|
|
115
|
+
return _generate_certificates_with_openssl(output_dir)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _generate_certificates_with_openssl(output_dir: Path) -> bool:
|
|
119
|
+
"""
|
|
120
|
+
Generate certificates using OpenSSL as fallback.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
output_dir: Directory to generate certificates in
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
True if certificates were generated successfully, False otherwise
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
print("🔐 Generating certificates using OpenSSL...")
|
|
130
|
+
|
|
131
|
+
# Create certificate directories
|
|
132
|
+
certs_dir = output_dir / "certs"
|
|
133
|
+
keys_dir = output_dir / "keys"
|
|
134
|
+
certs_dir.mkdir(parents=True, exist_ok=True)
|
|
135
|
+
keys_dir.mkdir(parents=True, exist_ok=True)
|
|
136
|
+
|
|
137
|
+
# Generate CA private key
|
|
138
|
+
ca_key_path = keys_dir / "ca_key.pem"
|
|
139
|
+
subprocess.run([
|
|
140
|
+
"openssl", "genrsa", "-out", str(ca_key_path), "2048"
|
|
141
|
+
], check=True)
|
|
142
|
+
|
|
143
|
+
# Generate CA certificate
|
|
144
|
+
ca_cert_path = certs_dir / "ca_cert.pem"
|
|
145
|
+
subprocess.run([
|
|
146
|
+
"openssl", "req", "-new", "-x509", "-key", str(ca_key_path),
|
|
147
|
+
"-out", str(ca_cert_path), "-days", "365",
|
|
148
|
+
"-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=MCP Test CA"
|
|
149
|
+
], check=True)
|
|
150
|
+
|
|
151
|
+
# Generate server private key
|
|
152
|
+
server_key_path = keys_dir / "server_key.pem"
|
|
153
|
+
subprocess.run([
|
|
154
|
+
"openssl", "genrsa", "-out", str(server_key_path), "2048"
|
|
155
|
+
], check=True)
|
|
156
|
+
|
|
157
|
+
# Generate server certificate request
|
|
158
|
+
server_csr_path = certs_dir / "server.csr"
|
|
159
|
+
subprocess.run([
|
|
160
|
+
"openssl", "req", "-new", "-key", str(server_key_path),
|
|
161
|
+
"-out", str(server_csr_path),
|
|
162
|
+
"-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=localhost"
|
|
163
|
+
], check=True)
|
|
164
|
+
|
|
165
|
+
# Generate server certificate
|
|
166
|
+
server_cert_path = certs_dir / "localhost_server.crt"
|
|
167
|
+
subprocess.run([
|
|
168
|
+
"openssl", "x509", "-req", "-in", str(server_csr_path),
|
|
169
|
+
"-CA", str(ca_cert_path), "-CAkey", str(ca_key_path),
|
|
170
|
+
"-out", str(server_cert_path), "-days", "365",
|
|
171
|
+
"-CAcreateserial"
|
|
172
|
+
], check=True)
|
|
173
|
+
|
|
174
|
+
# Generate client private key
|
|
175
|
+
client_key_path = keys_dir / "client_key.pem"
|
|
176
|
+
subprocess.run([
|
|
177
|
+
"openssl", "genrsa", "-out", str(client_key_path), "2048"
|
|
178
|
+
], check=True)
|
|
179
|
+
|
|
180
|
+
# Generate client certificate request
|
|
181
|
+
client_csr_path = certs_dir / "client.csr"
|
|
182
|
+
subprocess.run([
|
|
183
|
+
"openssl", "req", "-new", "-key", str(client_key_path),
|
|
184
|
+
"-out", str(client_csr_path),
|
|
185
|
+
"-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=test-client"
|
|
186
|
+
], check=True)
|
|
187
|
+
|
|
188
|
+
# Generate client certificate
|
|
189
|
+
client_cert_path = certs_dir / "client_cert.pem"
|
|
190
|
+
subprocess.run([
|
|
191
|
+
"openssl", "x509", "-req", "-in", str(client_csr_path),
|
|
192
|
+
"-CA", str(ca_cert_path), "-CAkey", str(ca_key_path),
|
|
193
|
+
"-out", str(client_cert_path), "-days", "365"
|
|
194
|
+
], check=True)
|
|
195
|
+
|
|
196
|
+
# Clean up CSR files
|
|
197
|
+
server_csr_path.unlink(missing_ok=True)
|
|
198
|
+
client_csr_path.unlink(missing_ok=True)
|
|
199
|
+
|
|
200
|
+
print("✅ Certificates generated successfully with OpenSSL!")
|
|
201
|
+
print(f" CA Certificate: {ca_cert_path}")
|
|
202
|
+
print(f" Server Certificate: {server_cert_path}")
|
|
203
|
+
print(f" Client Certificate: {client_cert_path}")
|
|
204
|
+
|
|
205
|
+
return True
|
|
206
|
+
|
|
207
|
+
except subprocess.CalledProcessError as e:
|
|
208
|
+
print(f"❌ OpenSSL command failed: {e}")
|
|
209
|
+
return False
|
|
210
|
+
except FileNotFoundError:
|
|
211
|
+
print("❌ OpenSSL not found. Please install OpenSSL or mcp_security_framework")
|
|
212
|
+
return False
|
|
213
|
+
except Exception as e:
|
|
214
|
+
print(f"❌ Error generating certificates with OpenSSL: {e}")
|
|
215
|
+
return False
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Configuration validator for MCP Proxy Adapter test environment setup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, List, Any, Tuple
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ConfigurationValidator:
|
|
12
|
+
"""
|
|
13
|
+
Validates MCP Proxy Adapter configurations for mutually exclusive settings
|
|
14
|
+
and protocol compatibility.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.errors: List[str] = []
|
|
19
|
+
self.warnings: List[str] = []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _validate_protocol_settings(
|
|
23
|
+
self, config: Dict[str, Any], config_name: str
|
|
24
|
+
) -> None:
|
|
25
|
+
"""Validate protocol configuration settings."""
|
|
26
|
+
protocols = config.get("protocols", {})
|
|
27
|
+
|
|
28
|
+
if not protocols.get("enabled", False):
|
|
29
|
+
self.warnings.append(
|
|
30
|
+
f"⚠️ {config_name}: Protocol middleware is disabled - all protocols will be allowed"
|
|
31
|
+
)
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
allowed_protocols = protocols.get("allowed_protocols", [])
|
|
35
|
+
if not allowed_protocols:
|
|
36
|
+
self.errors.append(
|
|
37
|
+
f"❌ {config_name}: No allowed protocols specified when protocol middleware is enabled"
|
|
38
|
+
)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
# Check for invalid protocol combinations
|
|
42
|
+
if "http" in allowed_protocols and "https" in allowed_protocols:
|
|
43
|
+
self.warnings.append(
|
|
44
|
+
f"⚠️ {config_name}: Both HTTP and HTTPS protocols are allowed - consider security implications"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if "mtls" in allowed_protocols and "http" in allowed_protocols:
|
|
48
|
+
self.errors.append(
|
|
49
|
+
f"❌ {config_name}: mTLS and HTTP protocols are mutually exclusive - mTLS requires HTTPS"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def _validate_ssl_settings(self, config: Dict[str, Any], config_name: str) -> None:
|
|
53
|
+
"""Validate SSL/TLS configuration settings."""
|
|
54
|
+
security = config.get("security", {})
|
|
55
|
+
ssl = security.get("ssl", {})
|
|
56
|
+
|
|
57
|
+
if not ssl.get("enabled", False):
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
# Check certificate file requirements
|
|
61
|
+
cert_file = ssl.get("server_cert_file")
|
|
62
|
+
key_file = ssl.get("server_key_file")
|
|
63
|
+
|
|
64
|
+
if not cert_file or not key_file:
|
|
65
|
+
self.errors.append(
|
|
66
|
+
f"❌ {config_name}: SSL enabled but server certificate or key file not specified"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Check CA certificate requirements
|
|
70
|
+
ca_cert_file = ssl.get("ca_cert_file")
|
|
71
|
+
verify_server = ssl.get("verify_server", True)
|
|
72
|
+
|
|
73
|
+
if verify_server and not ca_cert_file:
|
|
74
|
+
self.warnings.append(
|
|
75
|
+
f"⚠️ {config_name}: Server verification enabled but no CA certificate specified"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def _validate_mtls_settings(self, config: Dict[str, Any], config_name: str) -> None:
|
|
79
|
+
"""Validate mTLS configuration settings."""
|
|
80
|
+
security = config.get("security", {})
|
|
81
|
+
ssl = security.get("ssl", {})
|
|
82
|
+
|
|
83
|
+
if not ssl.get("enabled", False):
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
# Check if mTLS is configured
|
|
87
|
+
client_cert_file = ssl.get("client_cert_file")
|
|
88
|
+
client_key_file = ssl.get("client_key_file")
|
|
89
|
+
verify_client = ssl.get("verify_client", False)
|
|
90
|
+
|
|
91
|
+
if verify_client and (not client_cert_file or not client_key_file):
|
|
92
|
+
self.errors.append(
|
|
93
|
+
f"❌ {config_name}: Client verification enabled but client certificate or key file not specified"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Check protocol compatibility
|
|
97
|
+
protocols = config.get("protocols", {})
|
|
98
|
+
if protocols.get("enabled", False):
|
|
99
|
+
allowed_protocols = protocols.get("allowed_protocols", [])
|
|
100
|
+
if verify_client and "mtls" not in allowed_protocols:
|
|
101
|
+
self.warnings.append(
|
|
102
|
+
f"⚠️ {config_name}: Client verification enabled but 'mtls' not in allowed protocols"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def _validate_auth_settings(self, config: Dict[str, Any], config_name: str) -> None:
|
|
106
|
+
"""Validate authentication configuration settings."""
|
|
107
|
+
security = config.get("security", {})
|
|
108
|
+
auth = security.get("auth", {})
|
|
109
|
+
|
|
110
|
+
if not auth.get("enabled", False):
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
# Check token requirements
|
|
114
|
+
token_required = auth.get("token_required", False)
|
|
115
|
+
if token_required and not auth.get("token_secret"):
|
|
116
|
+
self.errors.append(
|
|
117
|
+
f"❌ {config_name}: Token authentication enabled but no token secret specified"
|
|
118
|
+
)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Environment setup for MCP Proxy Adapter test environment.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import bool
|
|
11
|
+
|
|
12
|
+
from .config_generator import create_configuration_documentation, generate_enhanced_configurations
|
|
13
|
+
from .test_files_generator import create_test_files
|
|
14
|
+
from .certificate_manager import generate_certificates_with_framework
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _create_directory_structure(output_dir: Path) -> None:
|
|
20
|
+
"""Create the required directory structure."""
|
|
21
|
+
directories = [
|
|
22
|
+
"configs",
|
|
23
|
+
"certs",
|
|
24
|
+
"keys",
|
|
25
|
+
"docs",
|
|
26
|
+
"examples",
|
|
27
|
+
"logs"
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
for directory in directories:
|
|
31
|
+
dir_path = output_dir / directory
|
|
32
|
+
dir_path.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
print(f" Created: {dir_path}")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _copy_example_files(output_dir: Path) -> None:
|
|
37
|
+
"""Copy example files from the package."""
|
|
38
|
+
try:
|
|
39
|
+
# Get package paths
|
|
40
|
+
package_path = Path(__file__).parent.parent.parent.parent
|
|
41
|
+
examples_path = package_path / "examples"
|
|
42
|
+
|
|
43
|
+
# Copy example files
|
|
44
|
+
examples_dest = output_dir / "examples"
|
|
45
|
+
if examples_path.exists():
|
|
46
|
+
shutil.copytree(examples_path, examples_dest, dirs_exist_ok=True)
|
|
47
|
+
print(f" Copied examples to: {examples_dest}")
|
|
48
|
+
else:
|
|
49
|
+
print(" ⚠️ Examples directory not found, skipping...")
|
|
50
|
+
|
|
51
|
+
except Exception as e:
|
|
52
|
+
print(f" ⚠️ Error copying example files: {e}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _create_setup_completion_marker(output_dir: Path) -> None:
|
|
56
|
+
"""Create a marker file indicating setup completion."""
|
|
57
|
+
marker_file = output_dir / ".setup_complete"
|
|
58
|
+
with open(marker_file, "w", encoding="utf-8") as f:
|
|
59
|
+
f.write("MCP Proxy Adapter test environment setup completed successfully.\n")
|
|
60
|
+
f.write("Generated by setup_test_environment.py\n")
|
|
61
|
+
|
|
62
|
+
print(f" Created setup marker: {marker_file}")
|