mcp-proxy-adapter 6.4.36__tar.gz → 6.4.39__tar.gz
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-6.4.36 → mcp_proxy_adapter-6.4.39}/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/create_test_configs.py +6 -31
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/run_full_test_suite.py +66 -52
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/run_security_tests.py +79 -24
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/security_test_client.py +17 -25
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/setup_test_environment.py +91 -98
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/pyproject.toml +1 -1
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/README.md +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/__main__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/app.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/handlers.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/base.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/error_handling.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/factory.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/logging.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/performance.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/protocol_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/unified_security.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/schemas.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/tool_integration.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/api/tools.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/auth_validation_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/base.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/builtin_commands.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/catalog_manager.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/cert_monitor_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/certificate_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/command_registry.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/config_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/dependency_container.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/dependency_manager.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/echo_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/health_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/help_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/hooks.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/key_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/load_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/plugins_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/protocol_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/proxy_registration_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/reload_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/result.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/role_test_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/roles_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/security_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/settings_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/ssl_setup_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/token_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/transport_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/commands/unload_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/config.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/app_factory.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/app_runner.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/auth_validator.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/certificate_utils.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/client.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/client_manager.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/client_security.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/config_converter.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/config_validator.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/crl_utils.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/errors.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/logging.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/mtls_asgi.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/mtls_asgi_app.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/mtls_server.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/protocol_manager.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/proxy_client.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/proxy_registration.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/role_utils.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/security_adapter.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/security_factory.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/security_integration.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/server_adapter.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/server_engine.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/settings.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/ssl_utils.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/transport_manager.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/unified_config_adapter.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/core/utils.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/custom_openapi.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/basic_framework/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/basic_framework/main.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/create_certificates_simple.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/debug_request_state.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/debug_role_chain.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/demo_client.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/main.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/generate_all_certificates.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/generate_certificates.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/generate_test_configs.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/proxy_registration_example.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/run_example.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/run_proxy_server.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/scripts/config_generator.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/test_config.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/test_config_generator.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/test_examples.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/examples/universal_client.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/main.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter/openapi.py +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/SOURCES.txt +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/dependency_links.txt +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/not-zip-safe +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/requires.txt +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/mcp_proxy_adapter.egg-info/top_level.txt +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/setup.cfg +0 -0
- {mcp_proxy_adapter-6.4.36 → mcp_proxy_adapter-6.4.39}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-proxy-adapter
|
3
|
-
Version: 6.4.
|
3
|
+
Version: 6.4.39
|
4
4
|
Summary: Powerful JSON-RPC microservices framework with built-in security, authentication, and proxy registration
|
5
5
|
Home-page: https://github.com/maverikod/mcp-proxy-adapter
|
6
6
|
Author: Vasiliy Zdanovskiy
|
@@ -175,7 +175,8 @@ class TestConfigGenerator:
|
|
175
175
|
"security.auth.methods": ["certificate"],
|
176
176
|
"security.permissions.enabled": False,
|
177
177
|
"proxy_registration.enabled": False,
|
178
|
-
"protocols.allowed_protocols": ["https", "mtls"]
|
178
|
+
"protocols.allowed_protocols": ["https", "mtls"],
|
179
|
+
"protocols.default_protocol": "mtls"
|
179
180
|
})
|
180
181
|
|
181
182
|
# 7. mTLS with Proxy Registration
|
@@ -196,37 +197,11 @@ class TestConfigGenerator:
|
|
196
197
|
"protocols.allowed_protocols": ["https", "mtls"]
|
197
198
|
})
|
198
199
|
|
199
|
-
# 8. HTTP with Token Auth (for security tests)
|
200
|
-
|
201
|
-
"server.port": 8010,
|
202
|
-
"ssl.enabled": False,
|
203
|
-
"security.enabled": True,
|
204
|
-
"security.auth.enabled": True,
|
205
|
-
"security.auth.methods": ["api_key"],
|
206
|
-
"security.auth.api_keys": {
|
207
|
-
"admin": "admin-secret-key",
|
208
|
-
"user": "user-secret-key"
|
209
|
-
},
|
210
|
-
"proxy_registration.enabled": False,
|
211
|
-
"protocols.allowed_protocols": ["http"]
|
212
|
-
})
|
200
|
+
# 8. HTTP with Token Auth (for security tests) - REMOVED DUPLICATE
|
201
|
+
# This is already created above with correct port 20021
|
213
202
|
|
214
|
-
# 9. HTTPS with Token Auth (for security tests)
|
215
|
-
|
216
|
-
"server.port": 8011,
|
217
|
-
"ssl.enabled": True,
|
218
|
-
"ssl.cert_file": "certs/localhost_server.crt",
|
219
|
-
"ssl.key_file": "keys/localhost_server.key",
|
220
|
-
"security.enabled": True,
|
221
|
-
"security.auth.enabled": True,
|
222
|
-
"security.auth.methods": ["api_key"],
|
223
|
-
"security.auth.api_keys": {
|
224
|
-
"admin": "admin-secret-key",
|
225
|
-
"user": "user-secret-key"
|
226
|
-
},
|
227
|
-
"proxy_registration.enabled": False,
|
228
|
-
"protocols.allowed_protocols": ["https"]
|
229
|
-
})
|
203
|
+
# 9. HTTPS with Token Auth (for security tests) - REMOVED DUPLICATE
|
204
|
+
# This is already created above with correct port 20023
|
230
205
|
|
231
206
|
# 10. Full Featured (everything enabled)
|
232
207
|
self.create_config("full_featured", {
|
@@ -8,9 +8,7 @@ Automates the complete testing workflow.
|
|
8
8
|
import os
|
9
9
|
import sys
|
10
10
|
import subprocess
|
11
|
-
import time
|
12
11
|
from pathlib import Path
|
13
|
-
from typing import List, Dict, Optional
|
14
12
|
|
15
13
|
|
16
14
|
class FullTestSuiteRunner:
|
@@ -26,9 +24,9 @@ class FullTestSuiteRunner:
|
|
26
24
|
|
27
25
|
def print_step(self, step: str, description: str):
|
28
26
|
"""Print a formatted step header."""
|
29
|
-
print(f"\n{'='*60}")
|
27
|
+
print(f"\n{'=' * 60}")
|
30
28
|
print(f"🔧 STEP {step}: {description}")
|
31
|
-
print(f"{'='*60}")
|
29
|
+
print(f"{'=' * 60}")
|
32
30
|
|
33
31
|
def print_success(self, message: str):
|
34
32
|
"""Print a success message."""
|
@@ -114,8 +112,19 @@ class FullTestSuiteRunner:
|
|
114
112
|
self.print_step("3", "Certificate Generation")
|
115
113
|
|
116
114
|
try:
|
115
|
+
# Check if certificate generation script exists
|
116
|
+
cert_script = self.working_dir / "scripts" / "create_certificates_simple.py"
|
117
|
+
if not cert_script.exists():
|
118
|
+
# Try alternative path
|
119
|
+
cert_script = self.working_dir / "create_certificates_simple.py"
|
120
|
+
if not cert_script.exists():
|
121
|
+
self.print_error(
|
122
|
+
f"Certificate generation script not found: {cert_script}"
|
123
|
+
)
|
124
|
+
return False
|
125
|
+
|
117
126
|
# Run certificate generation script
|
118
|
-
cmd = [sys.executable,
|
127
|
+
cmd = [sys.executable, str(cert_script)]
|
119
128
|
self.print_info("Running certificate generation script...")
|
120
129
|
|
121
130
|
result = subprocess.run(
|
@@ -152,18 +161,29 @@ class FullTestSuiteRunner:
|
|
152
161
|
# Check if comprehensive_config.json exists
|
153
162
|
comprehensive_config = self.working_dir / "comprehensive_config.json"
|
154
163
|
if not comprehensive_config.exists():
|
155
|
-
self.print_error(
|
164
|
+
self.print_error(
|
165
|
+
f"Comprehensive config not found: {comprehensive_config}"
|
166
|
+
)
|
156
167
|
return False
|
157
168
|
|
158
|
-
self.print_info(
|
169
|
+
self.print_info(
|
170
|
+
"Generating test configurations from comprehensive config..."
|
171
|
+
)
|
159
172
|
self.print_info("This will create:")
|
160
173
|
self.print_info(" - HTTP configurations (simple and with auth)")
|
161
174
|
self.print_info(" - HTTPS configurations (simple and with auth)")
|
162
|
-
self.print_info(
|
175
|
+
self.print_info(
|
176
|
+
" - mTLS configurations (simple, with roles, with proxy registration)"
|
177
|
+
)
|
163
178
|
self.print_info(" - Full featured configuration (everything enabled)")
|
164
179
|
|
165
180
|
# Run the configuration generator
|
166
|
-
cmd = [
|
181
|
+
cmd = [
|
182
|
+
sys.executable,
|
183
|
+
"create_test_configs.py",
|
184
|
+
"--comprehensive-config",
|
185
|
+
"comprehensive_config.json",
|
186
|
+
]
|
167
187
|
result = subprocess.run(
|
168
188
|
cmd, capture_output=True, text=True, cwd=self.working_dir
|
169
189
|
)
|
@@ -173,36 +193,37 @@ class FullTestSuiteRunner:
|
|
173
193
|
if result.stdout:
|
174
194
|
print("Generator output:")
|
175
195
|
print(result.stdout)
|
176
|
-
|
196
|
+
|
177
197
|
# Create roles.json file
|
178
198
|
self.print_info("Creating roles.json file...")
|
179
199
|
roles_content = {
|
180
200
|
"roles": {
|
181
201
|
"admin": {
|
182
202
|
"permissions": ["*"],
|
183
|
-
"description": "Full administrative access"
|
203
|
+
"description": "Full administrative access",
|
184
204
|
},
|
185
205
|
"user": {
|
186
206
|
"permissions": ["read", "write"],
|
187
|
-
"description": "Standard user access"
|
207
|
+
"description": "Standard user access",
|
188
208
|
},
|
189
209
|
"readonly": {
|
190
210
|
"permissions": ["read"],
|
191
|
-
"description": "Read-only access"
|
211
|
+
"description": "Read-only access",
|
192
212
|
},
|
193
213
|
"guest": {
|
194
214
|
"permissions": ["read"],
|
195
|
-
"description": "Limited guest access"
|
196
|
-
}
|
215
|
+
"description": "Limited guest access",
|
216
|
+
},
|
197
217
|
}
|
198
218
|
}
|
199
|
-
|
219
|
+
|
200
220
|
roles_file = self.configs_dir / "roles.json"
|
201
221
|
import json
|
202
|
-
|
222
|
+
|
223
|
+
with open(roles_file, "w", encoding="utf-8") as f:
|
203
224
|
json.dump(roles_content, f, indent=2, ensure_ascii=False)
|
204
225
|
self.print_success(f"Created roles.json: {roles_file}")
|
205
|
-
|
226
|
+
|
206
227
|
return True
|
207
228
|
else:
|
208
229
|
self.print_error("Configuration generation failed!")
|
@@ -287,29 +308,28 @@ class FullTestSuiteRunner:
|
|
287
308
|
# Create test_proxy_registration.json config if it doesn't exist
|
288
309
|
test_config = self.configs_dir / "test_proxy_registration.json"
|
289
310
|
if not test_config.exists():
|
290
|
-
self.print_info(
|
311
|
+
self.print_info(
|
312
|
+
"Creating test_proxy_registration.json configuration..."
|
313
|
+
)
|
291
314
|
test_config_content = {
|
292
315
|
"uuid": "550e8400-e29b-41d4-a716-446655440001",
|
293
|
-
"server": {
|
294
|
-
"host": "127.0.0.1",
|
295
|
-
"port": 20005
|
296
|
-
},
|
316
|
+
"server": {"host": "127.0.0.1", "port": 20006},
|
297
317
|
"ssl": {
|
298
318
|
"enabled": True,
|
299
319
|
"cert_file": "certs/localhost_server.crt",
|
300
|
-
"key_file": "keys/
|
320
|
+
"key_file": "keys/server_key.pem",
|
301
321
|
"ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
|
302
322
|
"client_cert_file": "certs/admin_cert.pem",
|
303
323
|
"client_key_file": "certs/admin_key.pem",
|
304
|
-
"verify_client": True
|
324
|
+
"verify_client": True,
|
305
325
|
},
|
306
326
|
"registration": {
|
307
327
|
"enabled": True,
|
308
328
|
"auth_method": "token",
|
309
|
-
"server_url": "
|
329
|
+
"server_url": "https://127.0.0.1:20005/proxy",
|
310
330
|
"token": {
|
311
331
|
"enabled": True,
|
312
|
-
"token": "proxy_registration_token_123"
|
332
|
+
"token": "proxy_registration_token_123",
|
313
333
|
},
|
314
334
|
"proxy_info": {
|
315
335
|
"name": "mcp_test_server",
|
@@ -317,50 +337,42 @@ class FullTestSuiteRunner:
|
|
317
337
|
"jsonrpc",
|
318
338
|
"rest",
|
319
339
|
"security",
|
320
|
-
"proxy_registration"
|
340
|
+
"proxy_registration",
|
321
341
|
],
|
322
342
|
"endpoints": {
|
323
343
|
"jsonrpc": "/api/jsonrpc",
|
324
344
|
"rest": "/cmd",
|
325
|
-
"health": "/health"
|
326
|
-
}
|
345
|
+
"health": "/health",
|
346
|
+
},
|
327
347
|
},
|
328
|
-
"heartbeat": {
|
329
|
-
"enabled": True,
|
330
|
-
"interval": 30
|
331
|
-
}
|
348
|
+
"heartbeat": {"enabled": True, "interval": 30},
|
332
349
|
},
|
333
350
|
"security": {
|
334
351
|
"enabled": True,
|
335
|
-
"auth": {
|
336
|
-
"enabled": True,
|
337
|
-
"methods": [
|
338
|
-
"certificate"
|
339
|
-
]
|
340
|
-
},
|
352
|
+
"auth": {"enabled": True, "methods": ["certificate"]},
|
341
353
|
"permissions": {
|
342
354
|
"enabled": True,
|
343
|
-
"roles_file": "configs/roles.json"
|
344
|
-
}
|
355
|
+
"roles_file": "configs/roles.json",
|
356
|
+
},
|
345
357
|
},
|
346
358
|
"protocols": {
|
347
359
|
"enabled": True,
|
348
360
|
"default_protocol": "mtls",
|
349
|
-
"allowed_protocols": [
|
350
|
-
|
351
|
-
"mtls"
|
352
|
-
]
|
353
|
-
}
|
361
|
+
"allowed_protocols": ["https", "mtls"],
|
362
|
+
},
|
354
363
|
}
|
355
|
-
|
364
|
+
|
356
365
|
import json
|
357
|
-
|
366
|
+
|
367
|
+
with open(test_config, "w", encoding="utf-8") as f:
|
358
368
|
json.dump(test_config_content, f, indent=2)
|
359
369
|
self.print_success(f"Created test configuration: {test_config}")
|
360
370
|
|
361
371
|
self.print_info("Running mTLS proxy registration test...")
|
362
372
|
self.print_info("This test verifies:")
|
363
|
-
self.print_info(
|
373
|
+
self.print_info(
|
374
|
+
" - mTLS server startup with client certificate verification"
|
375
|
+
)
|
364
376
|
self.print_info(" - Proxy registration functionality")
|
365
377
|
self.print_info(" - SSL configuration validation")
|
366
378
|
|
@@ -371,7 +383,9 @@ class FullTestSuiteRunner:
|
|
371
383
|
)
|
372
384
|
|
373
385
|
if result.returncode == 0:
|
374
|
-
self.print_success(
|
386
|
+
self.print_success(
|
387
|
+
"mTLS proxy registration test completed successfully!"
|
388
|
+
)
|
375
389
|
if result.stdout:
|
376
390
|
print("Test output:")
|
377
391
|
print(result.stdout)
|
@@ -461,7 +475,7 @@ class FullTestSuiteRunner:
|
|
461
475
|
return False
|
462
476
|
|
463
477
|
# All steps completed successfully
|
464
|
-
print(f"\n{'='*60}")
|
478
|
+
print(f"\n{'=' * 60}")
|
465
479
|
print("🎉 FULL TEST SUITE COMPLETED SUCCESSFULLY!")
|
466
480
|
print("=" * 60)
|
467
481
|
print("✅ Environment validated")
|
@@ -25,10 +25,19 @@ import psutil
|
|
25
25
|
import requests
|
26
26
|
|
27
27
|
# Import security test client with proper module path
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
try:
|
29
|
+
from mcp_proxy_adapter.examples.security_test_client import (
|
30
|
+
SecurityTestClient,
|
31
|
+
TestResult,
|
32
|
+
)
|
33
|
+
except ImportError:
|
34
|
+
# Fallback to local import if package import fails
|
35
|
+
current_dir = Path(__file__).parent
|
36
|
+
sys.path.insert(0, str(current_dir))
|
37
|
+
from security_test_client import (
|
38
|
+
SecurityTestClient,
|
39
|
+
TestResult,
|
40
|
+
)
|
32
41
|
|
33
42
|
|
34
43
|
class SecurityTestRunner:
|
@@ -49,31 +58,31 @@ class SecurityTestRunner:
|
|
49
58
|
"basic_http": {
|
50
59
|
"config": "configs/http_simple.json",
|
51
60
|
"port": 20020, # Dedicated port
|
52
|
-
"url":
|
61
|
+
"url": "http://127.0.0.1:20020",
|
53
62
|
"auth": "none",
|
54
63
|
},
|
55
64
|
"http_token": {
|
56
65
|
"config": "configs/http_token.json",
|
57
66
|
"port": 20021, # Dedicated port
|
58
|
-
"url":
|
67
|
+
"url": "http://127.0.0.1:20021",
|
59
68
|
"auth": "api_key",
|
60
69
|
},
|
61
70
|
"https": {
|
62
71
|
"config": "configs/https_simple.json",
|
63
72
|
"port": 20022, # Dedicated port
|
64
|
-
"url":
|
73
|
+
"url": "https://127.0.0.1:20022",
|
65
74
|
"auth": "none",
|
66
75
|
},
|
67
76
|
"https_token": {
|
68
77
|
"config": "configs/https_token.json",
|
69
78
|
"port": 20023, # Dedicated port
|
70
|
-
"url":
|
79
|
+
"url": "https://127.0.0.1:20023",
|
71
80
|
"auth": "api_key",
|
72
81
|
},
|
73
82
|
"mtls": {
|
74
83
|
"config": "configs/mtls_no_roles.json",
|
75
84
|
"port": 20024, # Dedicated port
|
76
|
-
"url":
|
85
|
+
"url": "https://127.0.0.1:20024",
|
77
86
|
"auth": "certificate",
|
78
87
|
},
|
79
88
|
}
|
@@ -146,6 +155,17 @@ class SecurityTestRunner:
|
|
146
155
|
ports.append(cfg["port"])
|
147
156
|
return list(sorted(set(ports)))
|
148
157
|
|
158
|
+
def check_ports_available(self, ports: List[int]) -> Tuple[bool, List[int]]:
|
159
|
+
"""
|
160
|
+
Check if all ports in the list are available.
|
161
|
+
Returns (True, []) if all ports are free, (False, occupied_ports) otherwise.
|
162
|
+
"""
|
163
|
+
occupied_ports = []
|
164
|
+
for port in ports:
|
165
|
+
if self._port_in_use(port):
|
166
|
+
occupied_ports.append(port)
|
167
|
+
return len(occupied_ports) == 0, occupied_ports
|
168
|
+
|
149
169
|
def _validate_file(self, base: Path, path_value: Optional[str]) -> Tuple[bool, str]:
|
150
170
|
if not path_value:
|
151
171
|
return True, ""
|
@@ -229,13 +249,20 @@ class SecurityTestRunner:
|
|
229
249
|
"""Start a server in background."""
|
230
250
|
try:
|
231
251
|
print(f"🚀 Starting {name} server on port {port}...")
|
232
|
-
|
233
|
-
#
|
252
|
+
|
253
|
+
# Always ensure port is free before starting server
|
234
254
|
if self._port_in_use(port):
|
235
|
-
print(f"
|
236
|
-
|
237
|
-
|
238
|
-
|
255
|
+
print(f"🧹 Port {port} is in use, freeing it...")
|
256
|
+
self.ensure_ports_free([port])
|
257
|
+
time.sleep(1) # Give time for port to be freed
|
258
|
+
|
259
|
+
# Check again after freeing
|
260
|
+
if self._port_in_use(port):
|
261
|
+
print(
|
262
|
+
f"❌ Port {port} still in use after cleanup, cannot start {name}"
|
263
|
+
)
|
264
|
+
return None
|
265
|
+
|
239
266
|
# Start server in background
|
240
267
|
logs_dir = Path("logs")
|
241
268
|
logs_dir.mkdir(exist_ok=True)
|
@@ -293,11 +320,25 @@ class SecurityTestRunner:
|
|
293
320
|
"""Start the proxy server for server registration."""
|
294
321
|
try:
|
295
322
|
print("🚀 Starting proxy server...")
|
323
|
+
|
324
|
+
# Ensure proxy port is free
|
325
|
+
if self._port_in_use(self.proxy_port):
|
326
|
+
print(f"🧹 Proxy port {self.proxy_port} is in use, freeing it...")
|
327
|
+
self.ensure_ports_free([self.proxy_port])
|
328
|
+
time.sleep(1)
|
329
|
+
|
330
|
+
if self._port_in_use(self.proxy_port):
|
331
|
+
print(f"❌ Proxy port {self.proxy_port} still in use after cleanup")
|
332
|
+
return False
|
333
|
+
|
296
334
|
# Find the proxy server script
|
297
335
|
proxy_script = Path(__file__).parent / "run_proxy_server.py"
|
298
336
|
if not proxy_script.exists():
|
299
|
-
|
300
|
-
|
337
|
+
# Try alternative path
|
338
|
+
proxy_script = Path.cwd() / "run_proxy_server.py"
|
339
|
+
if not proxy_script.exists():
|
340
|
+
print("❌ Proxy server script not found")
|
341
|
+
return False
|
301
342
|
|
302
343
|
# Start proxy server
|
303
344
|
cmd = [
|
@@ -372,13 +413,27 @@ class SecurityTestRunner:
|
|
372
413
|
# Override SSL context for mTLS
|
373
414
|
client.create_ssl_context = client.create_ssl_context_for_mtls
|
374
415
|
async with client as client_session:
|
375
|
-
|
376
|
-
|
377
|
-
|
416
|
+
# Pass correct token for api_key authentication
|
417
|
+
if config["auth"] == "api_key":
|
418
|
+
results = await client_session.run_security_tests(
|
419
|
+
config["url"], config["auth"], token="admin-secret-key"
|
420
|
+
)
|
421
|
+
else:
|
422
|
+
results = await client_session.run_security_tests(
|
423
|
+
config["url"], config["auth"]
|
424
|
+
)
|
378
425
|
else:
|
379
426
|
# For other auth types, use default SSL context
|
380
427
|
async with SecurityTestClient(config["url"]) as client:
|
381
|
-
|
428
|
+
# Pass correct token for api_key authentication
|
429
|
+
if config["auth"] == "api_key":
|
430
|
+
results = await client.run_security_tests(
|
431
|
+
config["url"], config["auth"], token="admin-secret-key"
|
432
|
+
)
|
433
|
+
else:
|
434
|
+
results = await client.run_security_tests(
|
435
|
+
config["url"], config["auth"]
|
436
|
+
)
|
382
437
|
# Print summary for this server
|
383
438
|
passed = sum(1 for r in results if r.success)
|
384
439
|
total = len(results)
|
@@ -521,13 +576,13 @@ class SecurityTestRunner:
|
|
521
576
|
print("\n🔍 STEP 1: Complete Port Availability Check")
|
522
577
|
all_ports = self.get_all_ports()
|
523
578
|
print(f"📋 Required ports: {all_ports}")
|
524
|
-
|
579
|
+
|
525
580
|
# Check if ALL ports are available
|
526
581
|
ports_available, occupied_ports = self.check_ports_available(all_ports)
|
527
582
|
if not ports_available:
|
528
583
|
print(f"❌ CRITICAL: Ports are occupied: {occupied_ports}")
|
529
584
|
print("🧹 Attempting to free occupied ports...")
|
530
|
-
|
585
|
+
|
531
586
|
if not self.ensure_ports_free(all_ports):
|
532
587
|
print("❌ FAILED: Could not free occupied ports. Aborting tests.")
|
533
588
|
print("💡 Manual cleanup required:")
|
@@ -584,7 +639,7 @@ def main():
|
|
584
639
|
"--no-cleanup", action="store_true", help="Don't cleanup servers after tests"
|
585
640
|
)
|
586
641
|
parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
|
587
|
-
|
642
|
+
parser.parse_args()
|
588
643
|
|
589
644
|
# Determine the correct configs directory
|
590
645
|
current_dir = Path.cwd()
|
@@ -11,28 +11,26 @@ Author: Vasiliy Zdanovskiy
|
|
11
11
|
email: vasilyvz@gmail.com
|
12
12
|
"""
|
13
13
|
import asyncio
|
14
|
-
import json
|
15
14
|
import os
|
16
15
|
import ssl
|
17
16
|
import sys
|
18
17
|
import time
|
19
18
|
from pathlib import Path
|
20
|
-
from typing import Dict, List, Optional
|
19
|
+
from typing import Dict, List, Optional
|
21
20
|
from dataclasses import dataclass
|
22
|
-
import aiohttp
|
23
21
|
from aiohttp import ClientSession, ClientTimeout, TCPConnector
|
24
22
|
|
25
23
|
# Add project root to path for imports
|
26
|
-
project_root = Path(__file__).parent.parent.parent
|
27
24
|
current_dir = Path(__file__).parent
|
28
25
|
parent_dir = current_dir.parent
|
29
|
-
|
26
|
+
# Only add paths that are likely to exist and be useful
|
27
|
+
if parent_dir.exists():
|
28
|
+
sys.path.insert(0, str(parent_dir))
|
30
29
|
sys.path.insert(0, str(current_dir))
|
31
|
-
sys.path.insert(0, str(parent_dir))
|
32
30
|
|
33
31
|
# Import mcp_security_framework components
|
34
32
|
try:
|
35
|
-
from mcp_security_framework import SSLManager
|
33
|
+
from mcp_security_framework import SSLManager
|
36
34
|
from mcp_security_framework.schemas.config import SSLConfig
|
37
35
|
|
38
36
|
_MCP_SECURITY_AVAILABLE = True
|
@@ -43,9 +41,6 @@ except ImportError:
|
|
43
41
|
|
44
42
|
# Import cryptography components
|
45
43
|
try:
|
46
|
-
from cryptography import x509
|
47
|
-
from cryptography.hazmat.primitives import serialization
|
48
|
-
|
49
44
|
_CRYPTOGRAPHY_AVAILABLE = True
|
50
45
|
print("✅ cryptography available")
|
51
46
|
except ImportError:
|
@@ -111,19 +106,19 @@ class SecurityTestClient:
|
|
111
106
|
"proxy": "proxy-token-123",
|
112
107
|
"invalid": "invalid-token-999",
|
113
108
|
}
|
114
|
-
# Test certificates
|
109
|
+
# Test certificates - use relative paths
|
115
110
|
self.test_certificates = {
|
116
111
|
"admin": {
|
117
|
-
"cert": "
|
118
|
-
"key": "
|
112
|
+
"cert": "certs/admin_cert.pem",
|
113
|
+
"key": "certs/admin_key.pem",
|
119
114
|
},
|
120
115
|
"user": {
|
121
|
-
"cert": "
|
122
|
-
"key": "
|
116
|
+
"cert": "certs/user_cert.pem",
|
117
|
+
"key": "certs/user_key.pem",
|
123
118
|
},
|
124
119
|
"readonly": {
|
125
|
-
"cert": "
|
126
|
-
"key": "
|
120
|
+
"cert": "certs/readonly_cert.pem",
|
121
|
+
"key": "certs/readonly_key.pem",
|
127
122
|
},
|
128
123
|
}
|
129
124
|
|
@@ -227,6 +222,7 @@ class SecurityTestClient:
|
|
227
222
|
headers = {"Content-Type": "application/json"}
|
228
223
|
if auth_type == "api_key":
|
229
224
|
token = kwargs.get("token", "test-token-123")
|
225
|
+
print(f"🔍 DEBUG: Using token: {token}")
|
230
226
|
# Provide both common header styles to maximize compatibility
|
231
227
|
headers["X-API-Key"] = token
|
232
228
|
headers["Authorization"] = f"Bearer {token}"
|
@@ -430,9 +426,7 @@ class SecurityTestClient:
|
|
430
426
|
try:
|
431
427
|
if auth_type == "certificate":
|
432
428
|
# For mTLS, test with invalid/expired certificate or no certificate
|
433
|
-
import aiohttp
|
434
429
|
from aiohttp import ClientTimeout, TCPConnector
|
435
|
-
import ssl
|
436
430
|
|
437
431
|
# Create SSL context with wrong certificate (should be rejected)
|
438
432
|
ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
|
@@ -450,6 +444,8 @@ class SecurityTestClient:
|
|
450
444
|
timeout = ClientTimeout(total=10) # Shorter timeout
|
451
445
|
|
452
446
|
try:
|
447
|
+
import aiohttp
|
448
|
+
|
453
449
|
async with aiohttp.ClientSession(
|
454
450
|
timeout=timeout, connector=connector
|
455
451
|
) as temp_session:
|
@@ -474,11 +470,7 @@ class SecurityTestClient:
|
|
474
470
|
error_message=f"SECURITY ISSUE: mTLS server accepted connection without client certificate (status: {response.status})",
|
475
471
|
duration=duration,
|
476
472
|
)
|
477
|
-
except (
|
478
|
-
aiohttp.ClientError,
|
479
|
-
aiohttp.ServerDisconnectedError,
|
480
|
-
asyncio.TimeoutError,
|
481
|
-
) as e:
|
473
|
+
except (Exception,) as e:
|
482
474
|
# This is expected - server should reject connections without proper certificate
|
483
475
|
duration = time.time() - start_time
|
484
476
|
return TestResult(
|
@@ -797,7 +789,7 @@ class SecurityTestClient:
|
|
797
789
|
print(f"Total Tests: {total_tests}")
|
798
790
|
print(f"Passed: {passed_tests} ✅")
|
799
791
|
print(f"Failed: {failed_tests} ❌")
|
800
|
-
print(f"Success Rate: {(passed_tests/total_tests*100):.1f}%")
|
792
|
+
print(f"Success Rate: {(passed_tests / total_tests * 100):.1f}%")
|
801
793
|
if failed_tests > 0:
|
802
794
|
print("\n❌ Failed Tests:")
|
803
795
|
for result in self.test_results:
|