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,342 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Direct Security Framework Integration
|
|
3
|
+
|
|
4
|
+
This module provides direct integration with mcp_security_framework,
|
|
5
|
+
replacing all project security methods with framework calls.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import Dict, Any, List
|
|
12
|
+
|
|
13
|
+
# Direct imports from framework
|
|
14
|
+
try:
|
|
15
|
+
from mcp_security_framework import (
|
|
16
|
+
SecurityManager,
|
|
17
|
+
AuthManager,
|
|
18
|
+
CertificateManager,
|
|
19
|
+
PermissionManager,
|
|
20
|
+
RateLimiter,
|
|
21
|
+
)
|
|
22
|
+
from mcp_security_framework.schemas.config import (
|
|
23
|
+
SecurityConfig,
|
|
24
|
+
AuthConfig,
|
|
25
|
+
SSLConfig,
|
|
26
|
+
PermissionConfig,
|
|
27
|
+
RateLimitConfig,
|
|
28
|
+
CertificateConfig,
|
|
29
|
+
LoggingConfig,
|
|
30
|
+
)
|
|
31
|
+
from mcp_security_framework.schemas.models import (
|
|
32
|
+
AuthResult,
|
|
33
|
+
ValidationResult,
|
|
34
|
+
CertificatePair,
|
|
35
|
+
)
|
|
36
|
+
from mcp_security_framework.middleware.fastapi_middleware import (
|
|
37
|
+
FastAPISecurityMiddleware,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
SECURITY_FRAMEWORK_AVAILABLE = True
|
|
41
|
+
except ImportError as e:
|
|
42
|
+
# NO FALLBACK! mcp_security_framework is REQUIRED
|
|
43
|
+
raise RuntimeError(
|
|
44
|
+
f"CRITICAL: mcp_security_framework is required but not available: {e}. "
|
|
45
|
+
"Install it with: pip install mcp_security_framework>=1.2.8"
|
|
46
|
+
) from e
|
|
47
|
+
|
|
48
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SecurityIntegration:
|
|
52
|
+
"""
|
|
53
|
+
Direct integration with mcp_security_framework.
|
|
54
|
+
|
|
55
|
+
This class replaces all project security methods with direct calls
|
|
56
|
+
to the security framework components.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __init__(self, config: Dict[str, Any]):
|
|
60
|
+
"""
|
|
61
|
+
Initialize security integration.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
config: Configuration dictionary
|
|
65
|
+
"""
|
|
66
|
+
if not SECURITY_FRAMEWORK_AVAILABLE:
|
|
67
|
+
raise ImportError("mcp_security_framework is not available")
|
|
68
|
+
|
|
69
|
+
self.config = config
|
|
70
|
+
self.security_config = self._create_security_config()
|
|
71
|
+
|
|
72
|
+
# Initialize framework components
|
|
73
|
+
self.security_manager = SecurityManager(self.security_config)
|
|
74
|
+
self.permission_manager = PermissionManager(self.security_config.permissions)
|
|
75
|
+
self.auth_manager = AuthManager(
|
|
76
|
+
self.security_config.auth, self.permission_manager
|
|
77
|
+
)
|
|
78
|
+
self.certificate_manager = CertificateManager(self.security_config.certificates)
|
|
79
|
+
self.rate_limiter = RateLimiter(self.security_config.rate_limit)
|
|
80
|
+
|
|
81
|
+
get_global_logger().info("Security integration initialized with mcp_security_framework")
|
|
82
|
+
|
|
83
|
+
def _create_security_config(self) -> SecurityConfig:
|
|
84
|
+
"""Create SecurityConfig from project configuration."""
|
|
85
|
+
# self.config is already the security section passed from unified_security.py
|
|
86
|
+
security_section = self.config
|
|
87
|
+
|
|
88
|
+
# Create SSL config - SSL is handled by server protocol, not security config
|
|
89
|
+
ssl_config = SSLConfig(
|
|
90
|
+
enabled=False, # SSL is handled by server protocol
|
|
91
|
+
cert_file=None,
|
|
92
|
+
key_file=None,
|
|
93
|
+
ca_cert_file=None,
|
|
94
|
+
client_cert_file=None,
|
|
95
|
+
client_key_file=None,
|
|
96
|
+
verify_mode="CERT_REQUIRED",
|
|
97
|
+
min_tls_version="TLSv1.2",
|
|
98
|
+
check_hostname=True,
|
|
99
|
+
check_expiry=True,
|
|
100
|
+
expiry_warning_days=30,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Create auth config - use new simplified structure
|
|
104
|
+
auth_config = AuthConfig(
|
|
105
|
+
enabled=security_section.get("enabled", True),
|
|
106
|
+
methods=["api_key"], # Use token-based authentication
|
|
107
|
+
api_keys=security_section.get("tokens", {}),
|
|
108
|
+
user_roles={}, # Will be handled by permissions
|
|
109
|
+
jwt_secret=None,
|
|
110
|
+
jwt_algorithm="HS256",
|
|
111
|
+
jwt_expiry_hours=24,
|
|
112
|
+
certificate_auth=False,
|
|
113
|
+
public_paths=[],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# Create permission config - use new simplified structure
|
|
117
|
+
roles = security_section.get("roles", {})
|
|
118
|
+
roles_file = security_section.get("roles_file")
|
|
119
|
+
|
|
120
|
+
# Enable permissions if we have roles or roles_file
|
|
121
|
+
permissions_enabled = bool(roles or roles_file)
|
|
122
|
+
|
|
123
|
+
if permissions_enabled:
|
|
124
|
+
# If roles_file is None or empty string, don't pass it to avoid framework errors
|
|
125
|
+
if roles_file is None or roles_file == "":
|
|
126
|
+
get_global_logger().warning(
|
|
127
|
+
"roles_file is None or empty, permissions will use default configuration"
|
|
128
|
+
)
|
|
129
|
+
roles_file = None
|
|
130
|
+
|
|
131
|
+
permission_config = PermissionConfig(
|
|
132
|
+
enabled=True,
|
|
133
|
+
roles_file=roles_file,
|
|
134
|
+
default_role="guest",
|
|
135
|
+
admin_role="admin",
|
|
136
|
+
role_hierarchy={},
|
|
137
|
+
permission_cache_enabled=True,
|
|
138
|
+
permission_cache_ttl=300,
|
|
139
|
+
wildcard_permissions=False,
|
|
140
|
+
strict_mode=True,
|
|
141
|
+
roles=roles,
|
|
142
|
+
)
|
|
143
|
+
else:
|
|
144
|
+
# Create minimal permission config when permissions are disabled
|
|
145
|
+
permission_config = PermissionConfig(
|
|
146
|
+
enabled=False,
|
|
147
|
+
roles_file=None,
|
|
148
|
+
default_role="guest",
|
|
149
|
+
admin_role="admin",
|
|
150
|
+
role_hierarchy={},
|
|
151
|
+
permission_cache_enabled=False,
|
|
152
|
+
permission_cache_ttl=300,
|
|
153
|
+
wildcard_permissions=False,
|
|
154
|
+
strict_mode=False,
|
|
155
|
+
roles={},
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Create rate limit config - use defaults since rate_limit section doesn't exist in new structure
|
|
159
|
+
rate_limit_config = RateLimitConfig(
|
|
160
|
+
enabled=True,
|
|
161
|
+
default_requests_per_minute=60,
|
|
162
|
+
default_requests_per_hour=1000,
|
|
163
|
+
burst_limit=2,
|
|
164
|
+
window_size_seconds=60,
|
|
165
|
+
storage_backend="memory",
|
|
166
|
+
exempt_paths=[],
|
|
167
|
+
exempt_roles=[],
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Create certificate config - certificates are handled by server protocol
|
|
171
|
+
certificate_config = CertificateConfig(
|
|
172
|
+
enabled=False, # Certificates are handled by server protocol
|
|
173
|
+
ca_cert_path=None,
|
|
174
|
+
ca_key_path=None,
|
|
175
|
+
cert_storage_path="./certs",
|
|
176
|
+
key_storage_path="./keys",
|
|
177
|
+
default_validity_days=365,
|
|
178
|
+
key_size=2048,
|
|
179
|
+
hash_algorithm="sha256",
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Create logging config - use defaults since logging section doesn't exist in new structure
|
|
183
|
+
logging_config = LoggingConfig(
|
|
184
|
+
enabled=True,
|
|
185
|
+
level="INFO",
|
|
186
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
187
|
+
console_output=True,
|
|
188
|
+
file_path=None,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Create main security config
|
|
192
|
+
return SecurityConfig(
|
|
193
|
+
ssl=ssl_config,
|
|
194
|
+
auth=auth_config,
|
|
195
|
+
permissions=permission_config,
|
|
196
|
+
rate_limit=rate_limit_config,
|
|
197
|
+
certificates=certificate_config,
|
|
198
|
+
logging=logging_config,
|
|
199
|
+
debug=security_section.get("debug", False),
|
|
200
|
+
environment=security_section.get("environment", "dev"),
|
|
201
|
+
version=security_section.get("version", "1.0.0"),
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Authentication methods - direct calls to AuthManager
|
|
205
|
+
async def authenticate_api_key(self, api_key: str) -> AuthResult:
|
|
206
|
+
"""Authenticate using API key."""
|
|
207
|
+
return await self.auth_manager.authenticate_api_key(api_key)
|
|
208
|
+
|
|
209
|
+
async def authenticate_jwt(self, token: str) -> AuthResult:
|
|
210
|
+
"""Authenticate using JWT token."""
|
|
211
|
+
return await self.auth_manager.authenticate_jwt(token)
|
|
212
|
+
|
|
213
|
+
async def authenticate_certificate(self, cert_data: bytes) -> AuthResult:
|
|
214
|
+
"""Authenticate using certificate."""
|
|
215
|
+
return await self.auth_manager.authenticate_certificate(cert_data)
|
|
216
|
+
|
|
217
|
+
async def validate_request(self, request_data: Dict[str, Any]) -> ValidationResult:
|
|
218
|
+
"""Validate request using security manager."""
|
|
219
|
+
return await self.security_manager.validate_request(request_data)
|
|
220
|
+
|
|
221
|
+
# Certificate methods - direct calls to CertificateManager
|
|
222
|
+
async def create_ca_certificate(
|
|
223
|
+
self, common_name: str, **kwargs
|
|
224
|
+
) -> CertificatePair:
|
|
225
|
+
"""Create CA certificate."""
|
|
226
|
+
return await self.certificate_manager.create_ca_certificate(
|
|
227
|
+
common_name, **kwargs
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
async def create_client_certificate(
|
|
231
|
+
self, common_name: str, **kwargs
|
|
232
|
+
) -> CertificatePair:
|
|
233
|
+
"""Create client certificate."""
|
|
234
|
+
return await self.certificate_manager.create_client_certificate(
|
|
235
|
+
common_name, **kwargs
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
async def create_server_certificate(
|
|
239
|
+
self, common_name: str, **kwargs
|
|
240
|
+
) -> CertificatePair:
|
|
241
|
+
"""Create server certificate."""
|
|
242
|
+
return await self.certificate_manager.create_server_certificate(
|
|
243
|
+
common_name, **kwargs
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
async def validate_certificate(self, cert_path: str) -> bool:
|
|
247
|
+
"""Validate certificate with CRL check if enabled."""
|
|
248
|
+
try:
|
|
249
|
+
# Get CRL configuration from security config
|
|
250
|
+
crl_config = None
|
|
251
|
+
if hasattr(self.security_config, "certificates"):
|
|
252
|
+
cert_config = self.security_config.certificates
|
|
253
|
+
# Only analyze CRL paths if certificates are enabled
|
|
254
|
+
if (
|
|
255
|
+
hasattr(cert_config, "enabled")
|
|
256
|
+
and cert_config.enabled
|
|
257
|
+
and hasattr(cert_config, "crl_enabled")
|
|
258
|
+
and cert_config.crl_enabled
|
|
259
|
+
):
|
|
260
|
+
crl_config = {
|
|
261
|
+
"crl_enabled": cert_config.crl_enabled,
|
|
262
|
+
"crl_path": getattr(cert_config, "crl_path", None),
|
|
263
|
+
"crl_url": getattr(cert_config, "crl_url", None),
|
|
264
|
+
"crl_validity_days": getattr(
|
|
265
|
+
cert_config, "crl_validity_days", 30
|
|
266
|
+
),
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
# Use mcp_security_framework's validate_certificate_chain with CRL
|
|
270
|
+
if crl_config and crl_config.get("crl_enabled"):
|
|
271
|
+
from mcp_security_framework.utils.cert_utils import (
|
|
272
|
+
validate_certificate_chain,
|
|
273
|
+
)
|
|
274
|
+
from .crl_utils import CRLManager
|
|
275
|
+
|
|
276
|
+
# Get CRL data
|
|
277
|
+
crl_manager = CRLManager(crl_config)
|
|
278
|
+
crl_data = crl_manager.get_crl_data()
|
|
279
|
+
|
|
280
|
+
# Validate with CRL
|
|
281
|
+
if crl_data:
|
|
282
|
+
return validate_certificate_chain(
|
|
283
|
+
cert_path,
|
|
284
|
+
self.security_config.certificates.ca_cert_path,
|
|
285
|
+
crl_data,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Fallback to standard validation
|
|
289
|
+
return await self.certificate_manager.validate_certificate(cert_path)
|
|
290
|
+
|
|
291
|
+
except Exception as e:
|
|
292
|
+
get_global_logger().error(f"Certificate validation failed: {e}")
|
|
293
|
+
return False
|
|
294
|
+
|
|
295
|
+
async def extract_roles_from_certificate(self, cert_path: str) -> List[str]:
|
|
296
|
+
"""Extract roles from certificate."""
|
|
297
|
+
return await self.certificate_manager.extract_roles_from_certificate(cert_path)
|
|
298
|
+
|
|
299
|
+
async def revoke_certificate(self, cert_path: str) -> bool:
|
|
300
|
+
"""Revoke certificate."""
|
|
301
|
+
return await self.certificate_manager.revoke_certificate(cert_path)
|
|
302
|
+
|
|
303
|
+
# Permission methods - direct calls to PermissionManager
|
|
304
|
+
async def check_permission(self, user_id: str, permission: str) -> bool:
|
|
305
|
+
"""Check user permission."""
|
|
306
|
+
return await self.permission_manager.check_permission(user_id, permission)
|
|
307
|
+
|
|
308
|
+
async def get_user_roles(self, user_id: str) -> List[str]:
|
|
309
|
+
"""Get user roles."""
|
|
310
|
+
return await self.permission_manager.get_user_roles(user_id)
|
|
311
|
+
|
|
312
|
+
async def add_user_role(self, user_id: str, role: str) -> bool:
|
|
313
|
+
"""Add role to user."""
|
|
314
|
+
return await self.permission_manager.add_user_role(user_id, role)
|
|
315
|
+
|
|
316
|
+
async def remove_user_role(self, user_id: str, role: str) -> bool:
|
|
317
|
+
"""Remove role from user."""
|
|
318
|
+
return await self.permission_manager.remove_user_role(user_id, role)
|
|
319
|
+
|
|
320
|
+
# Rate limiting methods - direct calls to RateLimiter
|
|
321
|
+
async def check_rate_limit(
|
|
322
|
+
self, identifier: str, limit_type: str = "per_minute"
|
|
323
|
+
) -> bool:
|
|
324
|
+
"""Check rate limit."""
|
|
325
|
+
return await self.rate_limiter.check_rate_limit(identifier, limit_type)
|
|
326
|
+
|
|
327
|
+
async def increment_rate_limit(self, identifier: str) -> None:
|
|
328
|
+
"""Increment rate limit counter."""
|
|
329
|
+
await self.rate_limiter.increment_rate_limit(identifier)
|
|
330
|
+
|
|
331
|
+
async def get_rate_limit_info(self, identifier: str) -> Dict[str, Any]:
|
|
332
|
+
"""Get rate limit information."""
|
|
333
|
+
return await self.rate_limiter.get_rate_limit_info(identifier)
|
|
334
|
+
|
|
335
|
+
# Middleware creation - direct use of framework middleware
|
|
336
|
+
|
|
337
|
+
# Utility methods
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
# Factory function for easy integration
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Server Configuration Adapter
|
|
3
|
+
|
|
4
|
+
This module provides adapters for converting configuration between different
|
|
5
|
+
server engines and handling SSL configuration mapping.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
from typing import Dict, Any, Optional
|
|
13
|
+
|
|
14
|
+
from .server_engine import ServerEngineFactory, ServerEngine
|
|
15
|
+
from .logging import get_global_logger
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ServerConfigAdapter:
|
|
21
|
+
"""
|
|
22
|
+
Adapter for converting server configurations between different engines.
|
|
23
|
+
|
|
24
|
+
This class handles the mapping of configuration parameters between
|
|
25
|
+
different server engines and provides unified configuration management.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def convert_ssl_config_for_engine(
|
|
30
|
+
ssl_config: Dict[str, Any], target_engine: str
|
|
31
|
+
) -> Dict[str, Any]:
|
|
32
|
+
"""
|
|
33
|
+
Convert SSL configuration for a specific server engine.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
ssl_config: Source SSL configuration
|
|
37
|
+
target_engine: Target engine name (hypercorn)
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Converted SSL configuration for the target engine
|
|
41
|
+
"""
|
|
42
|
+
engine = ServerEngineFactory.get_engine(target_engine)
|
|
43
|
+
if not engine:
|
|
44
|
+
get_global_logger().error(f"Unknown server engine: {target_engine}")
|
|
45
|
+
return {}
|
|
46
|
+
|
|
47
|
+
if target_engine == "hypercorn":
|
|
48
|
+
return ServerConfigAdapter._convert_to_hypercorn_ssl(ssl_config)
|
|
49
|
+
else:
|
|
50
|
+
get_global_logger().warning(f"No SSL conversion available for engine: {target_engine}")
|
|
51
|
+
return {}
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def _convert_to_hypercorn_ssl(ssl_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
55
|
+
"""Convert SSL configuration to hypercorn format."""
|
|
56
|
+
hypercorn_ssl = {}
|
|
57
|
+
|
|
58
|
+
# Map SSL parameters
|
|
59
|
+
if ssl_config.get("cert_file"):
|
|
60
|
+
hypercorn_ssl["certfile"] = ssl_config["cert_file"]
|
|
61
|
+
if ssl_config.get("key_file"):
|
|
62
|
+
hypercorn_ssl["keyfile"] = ssl_config["key_file"]
|
|
63
|
+
if ssl_config.get("ca_cert"):
|
|
64
|
+
hypercorn_ssl["ca_certs"] = ssl_config["ca_cert"]
|
|
65
|
+
|
|
66
|
+
# Map verification mode
|
|
67
|
+
if ssl_config.get("verify_client", False):
|
|
68
|
+
hypercorn_ssl["verify_mode"] = 2 # ssl.CERT_REQUIRED
|
|
69
|
+
|
|
70
|
+
# Map hostname checking
|
|
71
|
+
if "chk_hostname" in ssl_config:
|
|
72
|
+
hypercorn_ssl["check_hostname"] = ssl_config["chk_hostname"]
|
|
73
|
+
|
|
74
|
+
get_global_logger().debug(f"Converted SSL config to hypercorn: {hypercorn_ssl}")
|
|
75
|
+
return hypercorn_ssl
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def validate_engine_compatibility(config: Dict[str, Any], engine_name: str) -> bool:
|
|
81
|
+
"""
|
|
82
|
+
Validate if a configuration is compatible with a specific engine.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
config: Server configuration
|
|
86
|
+
engine_name: Name of the server engine
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
True if compatible, False otherwise
|
|
90
|
+
"""
|
|
91
|
+
engine = ServerEngineFactory.get_engine(engine_name)
|
|
92
|
+
if not engine:
|
|
93
|
+
get_global_logger().error(f"Unknown engine: {engine_name}")
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
# Check SSL requirements
|
|
97
|
+
ssl_config = config.get("ssl", {})
|
|
98
|
+
if not ssl_config:
|
|
99
|
+
# Try to get SSL config from security section
|
|
100
|
+
ssl_config = config.get("security", {}).get("ssl", {})
|
|
101
|
+
|
|
102
|
+
if ssl_config.get("verify_client", False):
|
|
103
|
+
if not engine.get_supported_features().get("mtls_client_certs", False):
|
|
104
|
+
get_global_logger().error(
|
|
105
|
+
f"Engine {engine_name} doesn't support mTLS client certificates"
|
|
106
|
+
)
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
# Validate engine-specific configuration
|
|
110
|
+
return engine.validate_config(config)
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def get_engine_capabilities(engine_name: str) -> Dict[str, Any]:
|
|
114
|
+
"""
|
|
115
|
+
Get capabilities of a specific server engine.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
engine_name: Name of the server engine
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Dictionary of engine capabilities
|
|
122
|
+
"""
|
|
123
|
+
engine = ServerEngineFactory.get_engine(engine_name)
|
|
124
|
+
if not engine:
|
|
125
|
+
return {}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
"name": engine.get_name(),
|
|
129
|
+
"features": engine.get_supported_features(),
|
|
130
|
+
"config_schema": engine.get_config_schema(),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class UnifiedServerRunner:
|
|
135
|
+
"""
|
|
136
|
+
Unified server runner that uses hypercorn as the default engine.
|
|
137
|
+
|
|
138
|
+
This class provides a unified interface for running servers using hypercorn
|
|
139
|
+
as the underlying engine.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
def __init__(self, default_engine: str = "hypercorn"):
|
|
143
|
+
"""
|
|
144
|
+
Initialize the unified server runner.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
default_engine: Default engine to use (currently only hypercorn is supported)
|
|
148
|
+
"""
|
|
149
|
+
self.default_engine = default_engine
|
|
150
|
+
self.available_engines = ServerEngineFactory.get_available_engines()
|
|
151
|
+
|
|
152
|
+
get_global_logger().info(f"Available engines: {list(self.available_engines.keys())}")
|
|
153
|
+
get_global_logger().info(f"Default engine: {default_engine}")
|
|
154
|
+
|
|
155
|
+
def run_server(
|
|
156
|
+
self, app: Any, config: Dict[str, Any], engine_name: Optional[str] = None
|
|
157
|
+
) -> None:
|
|
158
|
+
"""
|
|
159
|
+
Run server with hypercorn engine.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
app: ASGI application
|
|
163
|
+
config: Server configuration
|
|
164
|
+
engine_name: Engine to use (currently only hypercorn is supported)
|
|
165
|
+
"""
|
|
166
|
+
# Use hypercorn as the only supported engine
|
|
167
|
+
selected_engine = "hypercorn"
|
|
168
|
+
get_global_logger().info(f"Using hypercorn engine")
|
|
169
|
+
|
|
170
|
+
# Validate compatibility
|
|
171
|
+
if not ServerConfigAdapter.validate_engine_compatibility(
|
|
172
|
+
config, selected_engine
|
|
173
|
+
):
|
|
174
|
+
raise ValueError(
|
|
175
|
+
f"Configuration not compatible with engine: {selected_engine}"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Get engine instance
|
|
179
|
+
engine = ServerEngineFactory.get_engine(selected_engine)
|
|
180
|
+
if not engine:
|
|
181
|
+
raise ValueError(f"Engine not available: {selected_engine}")
|
|
182
|
+
|
|
183
|
+
# Convert configuration if needed
|
|
184
|
+
converted_config = self._prepare_config_for_engine(config, selected_engine)
|
|
185
|
+
|
|
186
|
+
# Run server
|
|
187
|
+
get_global_logger().info(f"Starting server with {selected_engine} engine")
|
|
188
|
+
engine.run_server(app, converted_config)
|
|
189
|
+
|
|
190
|
+
def _prepare_config_for_engine(
|
|
191
|
+
self, config: Dict[str, Any], engine_name: str
|
|
192
|
+
) -> Dict[str, Any]:
|
|
193
|
+
get_global_logger().info(
|
|
194
|
+
f"🔍 Debug: _prepare_config_for_engine called with config keys: {list(config.keys())}"
|
|
195
|
+
)
|
|
196
|
+
get_global_logger().info(f"🔍 Debug: SSL config in input: {config.get('ssl', 'NOT_FOUND')}")
|
|
197
|
+
"""
|
|
198
|
+
Prepare configuration for a specific engine.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
config: Original configuration
|
|
202
|
+
engine_name: Target engine name
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
Engine-specific configuration
|
|
206
|
+
"""
|
|
207
|
+
# Start with basic config
|
|
208
|
+
engine_config = {
|
|
209
|
+
"host": config.get("host", "127.0.0.1"),
|
|
210
|
+
"port": config.get("port", 8000),
|
|
211
|
+
"log_level": config.get("log_level", "info"),
|
|
212
|
+
"reload": config.get("reload", False),
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
# Add SSL configuration if present
|
|
216
|
+
# First check for direct SSL parameters (from app_factory.py)
|
|
217
|
+
if (
|
|
218
|
+
"certfile" in config
|
|
219
|
+
or "keyfile" in config
|
|
220
|
+
or "ca_certs" in config
|
|
221
|
+
or "verify_mode" in config
|
|
222
|
+
):
|
|
223
|
+
get_global_logger().info(f"🔍 DEBUG: Direct SSL parameters found in config")
|
|
224
|
+
if "certfile" in config:
|
|
225
|
+
engine_config["certfile"] = config["certfile"]
|
|
226
|
+
if "keyfile" in config:
|
|
227
|
+
engine_config["keyfile"] = config["keyfile"]
|
|
228
|
+
if "ca_certs" in config:
|
|
229
|
+
engine_config["ca_certs"] = config["ca_certs"]
|
|
230
|
+
if "verify_mode" in config:
|
|
231
|
+
engine_config["verify_mode"] = config["verify_mode"]
|
|
232
|
+
else:
|
|
233
|
+
# Try to get SSL config from ssl section
|
|
234
|
+
ssl_config = config.get("ssl", {})
|
|
235
|
+
if not ssl_config:
|
|
236
|
+
# Try to get SSL config from security section
|
|
237
|
+
ssl_config = config.get("security", {}).get("ssl", {})
|
|
238
|
+
|
|
239
|
+
if ssl_config:
|
|
240
|
+
converted_ssl = ServerConfigAdapter.convert_ssl_config_for_engine(
|
|
241
|
+
ssl_config, engine_name
|
|
242
|
+
)
|
|
243
|
+
engine_config.update(converted_ssl)
|
|
244
|
+
|
|
245
|
+
# Add engine-specific configuration
|
|
246
|
+
if "workers" in config:
|
|
247
|
+
engine_config["workers"] = config["workers"]
|
|
248
|
+
|
|
249
|
+
return engine_config
|
|
250
|
+
|
|
251
|
+
|