mcp-proxy-adapter 6.0.0__py3-none-any.whl → 6.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_proxy_adapter/__main__.py +27 -7
- mcp_proxy_adapter/api/app.py +209 -79
- mcp_proxy_adapter/api/handlers.py +16 -5
- mcp_proxy_adapter/api/middleware/__init__.py +14 -9
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
- mcp_proxy_adapter/api/middleware/factory.py +36 -12
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +84 -18
- mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
- mcp_proxy_adapter/commands/__init__.py +7 -1
- mcp_proxy_adapter/commands/base.py +7 -4
- mcp_proxy_adapter/commands/builtin_commands.py +8 -2
- mcp_proxy_adapter/commands/command_registry.py +8 -0
- mcp_proxy_adapter/commands/echo_command.py +81 -0
- mcp_proxy_adapter/commands/health_command.py +1 -1
- mcp_proxy_adapter/commands/help_command.py +21 -14
- mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
- mcp_proxy_adapter/commands/role_test_command.py +141 -0
- mcp_proxy_adapter/commands/security_command.py +488 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +234 -351
- mcp_proxy_adapter/commands/token_management_command.py +1 -1
- mcp_proxy_adapter/config.py +323 -40
- mcp_proxy_adapter/core/app_factory.py +410 -0
- mcp_proxy_adapter/core/app_runner.py +272 -0
- mcp_proxy_adapter/core/certificate_utils.py +291 -73
- mcp_proxy_adapter/core/client.py +574 -0
- mcp_proxy_adapter/core/client_manager.py +284 -0
- mcp_proxy_adapter/core/client_security.py +384 -0
- mcp_proxy_adapter/core/logging.py +8 -3
- mcp_proxy_adapter/core/mtls_asgi.py +156 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/protocol_manager.py +169 -10
- mcp_proxy_adapter/core/proxy_client.py +602 -0
- mcp_proxy_adapter/core/proxy_registration.py +299 -47
- mcp_proxy_adapter/core/security_adapter.py +12 -15
- mcp_proxy_adapter/core/security_integration.py +286 -0
- mcp_proxy_adapter/core/server_adapter.py +282 -0
- mcp_proxy_adapter/core/server_engine.py +270 -0
- mcp_proxy_adapter/core/ssl_utils.py +13 -12
- mcp_proxy_adapter/core/transport_manager.py +5 -5
- mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
- mcp_proxy_adapter/examples/__init__.py +13 -4
- 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 +44 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
- mcp_proxy_adapter/examples/debug_request_state.py +112 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
- mcp_proxy_adapter/examples/demo_client.py +275 -0
- mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
- mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
- mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
- mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
- mcp_proxy_adapter/examples/full_application/main.py +173 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
- mcp_proxy_adapter/examples/generate_certificates.py +177 -0
- mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
- mcp_proxy_adapter/examples/run_example.py +59 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
- mcp_proxy_adapter/examples/run_security_tests.py +544 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
- mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
- mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
- mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/security_test_client.py +782 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
- mcp_proxy_adapter/examples/test_config.py +148 -0
- mcp_proxy_adapter/examples/test_config_generator.py +86 -0
- mcp_proxy_adapter/examples/test_examples.py +281 -0
- mcp_proxy_adapter/examples/universal_client.py +620 -0
- mcp_proxy_adapter/main.py +66 -148
- mcp_proxy_adapter/utils/config_generator.py +1008 -0
- mcp_proxy_adapter/version.py +5 -2
- mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
- mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
- mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
- {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
- mcp_proxy_adapter/api/middleware/auth.py +0 -146
- mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
- mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
- mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
- mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
- mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
- mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
- mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
- mcp_proxy_adapter/api/middleware/security.py +0 -376
- mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
- mcp_proxy_adapter/examples/README.md +0 -124
- mcp_proxy_adapter/examples/basic_server/README.md +0 -60
- mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
- mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
- mcp_proxy_adapter/examples/basic_server/config.json +0 -70
- mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
- mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
- mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
- mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
- mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
- mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
- mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
- mcp_proxy_adapter/examples/basic_server/server.py +0 -114
- mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
- mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
- mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
- mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
- mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
- mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
- mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
- mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
- mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
- mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
- mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
- mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
- mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
- mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
- mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
- mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
- mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
- mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
- mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
- mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
- mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
- mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
- mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
- mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
- mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
- mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
- mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
- mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
- mcp_proxy_adapter/examples/deployment/README.md +0 -49
- mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
- mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
- mcp_proxy_adapter/examples/deployment/config.json +0 -29
- mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
- mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
- mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
- mcp_proxy_adapter/examples/deployment/run.sh +0 -43
- mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
- mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
- mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
- mcp_proxy_adapter/schemas/base_schema.json +0 -114
- mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
- mcp_proxy_adapter/schemas/roles_schema.json +0 -162
- mcp_proxy_adapter/tests/__init__.py +0 -0
- mcp_proxy_adapter/tests/api/__init__.py +0 -3
- mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
- mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
- mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
- mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
- mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
- mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
- mcp_proxy_adapter/tests/commands/__init__.py +0 -3
- mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
- mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
- mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
- mcp_proxy_adapter/tests/conftest.py +0 -131
- mcp_proxy_adapter/tests/functional/__init__.py +0 -3
- mcp_proxy_adapter/tests/functional/test_api.py +0 -253
- mcp_proxy_adapter/tests/integration/__init__.py +0 -3
- mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
- mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
- mcp_proxy_adapter/tests/performance/__init__.py +0 -3
- mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
- mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
- mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
- mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
- mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
- mcp_proxy_adapter/tests/test_base_command.py +0 -123
- mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
- mcp_proxy_adapter/tests/test_command_registry.py +0 -281
- mcp_proxy_adapter/tests/test_config.py +0 -127
- mcp_proxy_adapter/tests/test_utils.py +0 -65
- mcp_proxy_adapter/tests/unit/__init__.py +0 -3
- mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
- mcp_proxy_adapter/tests/unit/test_config.py +0 -270
- mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
- mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
- {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/top_level.txt +0 -0
@@ -40,7 +40,7 @@ class TokenManagementCommand(Command):
|
|
40
40
|
self.logger = logging.getLogger(__name__)
|
41
41
|
|
42
42
|
# Load configuration
|
43
|
-
from
|
43
|
+
from ...config import config
|
44
44
|
self.token_config = config.get("ssl", {}).get("token_auth", {})
|
45
45
|
self.tokens_file = self.token_config.get("tokens_file", "tokens.json")
|
46
46
|
self.token_expiry = self.token_config.get("token_expiry", 3600)
|
mcp_proxy_adapter/config.py
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
"""
|
2
2
|
Module for microservice configuration management.
|
3
|
+
|
4
|
+
Author: Vasiliy Zdanovskiy
|
5
|
+
email: vasilyvz@gmail.com
|
3
6
|
"""
|
4
7
|
|
5
8
|
import json
|
6
9
|
import os
|
7
|
-
from
|
8
|
-
from typing import Any, Dict, Optional
|
10
|
+
from typing import Any, Dict, Optional, List
|
9
11
|
|
10
12
|
|
11
13
|
class Config:
|
12
14
|
"""
|
13
15
|
Configuration management class for the microservice.
|
14
16
|
Allows loading settings from configuration file and environment variables.
|
17
|
+
Supports optional features that can be enabled/disabled.
|
15
18
|
"""
|
16
19
|
|
17
20
|
def __init__(self, config_path: Optional[str] = None):
|
@@ -19,7 +22,8 @@ class Config:
|
|
19
22
|
Initialize configuration.
|
20
23
|
|
21
24
|
Args:
|
22
|
-
config_path: Path to configuration file. If not specified,
|
25
|
+
config_path: Path to configuration file. If not specified,
|
26
|
+
"./config.json" is used.
|
23
27
|
"""
|
24
28
|
self.config_path = config_path or "./config.json"
|
25
29
|
self.config_data: Dict[str, Any] = {}
|
@@ -53,10 +57,13 @@ class Config:
|
|
53
57
|
},
|
54
58
|
"commands": {
|
55
59
|
"auto_discovery": True,
|
56
|
-
"commands_directory": "./commands",
|
57
|
-
"catalog_directory": "./catalog",
|
58
|
-
"plugin_servers": [],
|
59
|
-
"auto_install_dependencies": True
|
60
|
+
"commands_directory": "./commands",
|
61
|
+
"catalog_directory": "./catalog",
|
62
|
+
"plugin_servers": [],
|
63
|
+
"auto_install_dependencies": True,
|
64
|
+
"enabled_commands": ["health", "echo", "list", "help"],
|
65
|
+
"disabled_commands": [],
|
66
|
+
"custom_commands_path": "./commands"
|
60
67
|
},
|
61
68
|
"ssl": {
|
62
69
|
"enabled": False,
|
@@ -66,8 +73,11 @@ class Config:
|
|
66
73
|
"ca_cert": None,
|
67
74
|
"verify_client": False,
|
68
75
|
"client_cert_required": False,
|
69
|
-
"cipher_suites": [
|
70
|
-
|
76
|
+
"cipher_suites": [
|
77
|
+
"TLS_AES_256_GCM_SHA384",
|
78
|
+
"TLS_CHACHA20_POLY1305_SHA256"
|
79
|
+
],
|
80
|
+
"min_tls_version": "TLSv1.2",
|
71
81
|
"max_tls_version": "1.3",
|
72
82
|
"token_auth": {
|
73
83
|
"enabled": False,
|
@@ -80,16 +90,16 @@ class Config:
|
|
80
90
|
}
|
81
91
|
},
|
82
92
|
"roles": {
|
83
|
-
"enabled":
|
84
|
-
"config_file":
|
93
|
+
"enabled": False,
|
94
|
+
"config_file": None,
|
85
95
|
"default_policy": {
|
86
|
-
"deny_by_default":
|
87
|
-
"require_role_match":
|
96
|
+
"deny_by_default": False,
|
97
|
+
"require_role_match": False,
|
88
98
|
"case_sensitive": False,
|
89
|
-
"allow_wildcard":
|
99
|
+
"allow_wildcard": False
|
90
100
|
},
|
91
|
-
"auto_load":
|
92
|
-
"validation_enabled":
|
101
|
+
"auto_load": False,
|
102
|
+
"validation_enabled": False
|
93
103
|
},
|
94
104
|
"transport": {
|
95
105
|
"type": "http",
|
@@ -121,40 +131,103 @@ class Config:
|
|
121
131
|
},
|
122
132
|
"security": {
|
123
133
|
"framework": "mcp_security_framework",
|
124
|
-
"enabled":
|
134
|
+
"enabled": False,
|
135
|
+
"debug": False,
|
136
|
+
"environment": "dev",
|
137
|
+
"version": "1.0.0",
|
125
138
|
"auth": {
|
126
|
-
"enabled":
|
139
|
+
"enabled": False,
|
127
140
|
"methods": ["api_key"],
|
128
141
|
"api_keys": {},
|
142
|
+
"user_roles": {},
|
129
143
|
"jwt_secret": "",
|
130
|
-
"jwt_algorithm": "HS256"
|
144
|
+
"jwt_algorithm": "HS256",
|
145
|
+
"jwt_expiry_hours": 24,
|
146
|
+
"certificate_auth": False,
|
147
|
+
"certificate_roles_oid": "1.3.6.1.4.1.99999.1.1",
|
148
|
+
"certificate_permissions_oid": "1.3.6.1.4.1.99999.1.2",
|
149
|
+
"basic_auth": False,
|
150
|
+
"oauth2_config": None,
|
151
|
+
"public_paths": ["/health", "/docs", "/openapi.json"],
|
152
|
+
"security_headers": None
|
131
153
|
},
|
132
154
|
"ssl": {
|
133
155
|
"enabled": False,
|
134
156
|
"cert_file": None,
|
135
157
|
"key_file": None,
|
136
|
-
"
|
158
|
+
"ca_cert_file": None,
|
159
|
+
"client_cert_file": None,
|
160
|
+
"client_key_file": None,
|
161
|
+
"verify_mode": "CERT_NONE",
|
137
162
|
"min_tls_version": "TLSv1.2",
|
138
|
-
"
|
139
|
-
"
|
163
|
+
"max_tls_version": None,
|
164
|
+
"cipher_suite": None,
|
165
|
+
"check_hostname": True,
|
166
|
+
"check_expiry": True,
|
167
|
+
"expiry_warning_days": 30
|
168
|
+
},
|
169
|
+
"certificates": {
|
170
|
+
"enabled": False,
|
171
|
+
"ca_cert_path": None,
|
172
|
+
"ca_key_path": None,
|
173
|
+
"cert_storage_path": "./certs",
|
174
|
+
"key_storage_path": "./keys",
|
175
|
+
"default_validity_days": 365,
|
176
|
+
"key_size": 2048,
|
177
|
+
"hash_algorithm": "sha256",
|
178
|
+
"crl_enabled": False,
|
179
|
+
"crl_path": None,
|
180
|
+
"crl_validity_days": 30,
|
181
|
+
"auto_renewal": False,
|
182
|
+
"renewal_threshold_days": 30
|
140
183
|
},
|
141
184
|
"permissions": {
|
142
|
-
"enabled":
|
143
|
-
"roles_file":
|
144
|
-
"default_role": "
|
145
|
-
"
|
185
|
+
"enabled": False,
|
186
|
+
"roles_file": None,
|
187
|
+
"default_role": "guest",
|
188
|
+
"admin_role": "admin",
|
189
|
+
"role_hierarchy": {},
|
190
|
+
"permission_cache_enabled": False,
|
191
|
+
"permission_cache_ttl": 300,
|
192
|
+
"wildcard_permissions": False,
|
193
|
+
"strict_mode": False,
|
194
|
+
"roles": None
|
146
195
|
},
|
147
196
|
"rate_limit": {
|
197
|
+
"enabled": False,
|
198
|
+
"default_requests_per_minute": 60,
|
199
|
+
"default_requests_per_hour": 1000,
|
200
|
+
"burst_limit": 2,
|
201
|
+
"window_size_seconds": 60,
|
202
|
+
"storage_backend": "memory",
|
203
|
+
"redis_config": None,
|
204
|
+
"cleanup_interval": 300,
|
205
|
+
"exempt_paths": ["/health", "/docs", "/openapi.json"],
|
206
|
+
"exempt_roles": ["admin"]
|
207
|
+
},
|
208
|
+
"logging": {
|
148
209
|
"enabled": True,
|
149
|
-
"
|
150
|
-
"
|
151
|
-
"
|
152
|
-
"
|
153
|
-
"
|
210
|
+
"level": "INFO",
|
211
|
+
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
212
|
+
"date_format": "%Y-%m-%d %H:%M:%S",
|
213
|
+
"file_path": None,
|
214
|
+
"max_file_size": 10,
|
215
|
+
"backup_count": 5,
|
216
|
+
"console_output": True,
|
217
|
+
"json_format": False,
|
218
|
+
"include_timestamp": True,
|
219
|
+
"include_level": True,
|
220
|
+
"include_module": True
|
154
221
|
}
|
222
|
+
},
|
223
|
+
"protocols": {
|
224
|
+
"enabled": True,
|
225
|
+
"allowed_protocols": ["http", "jsonrpc"],
|
226
|
+
"default_protocol": "http",
|
227
|
+
"auto_discovery": True
|
155
228
|
}
|
156
229
|
}
|
157
|
-
|
230
|
+
|
158
231
|
# Try to load configuration from file
|
159
232
|
if os.path.exists(self.config_path):
|
160
233
|
try:
|
@@ -163,7 +236,7 @@ class Config:
|
|
163
236
|
self._update_nested_dict(self.config_data, file_config)
|
164
237
|
except Exception as e:
|
165
238
|
print(f"Error loading config from {self.config_path}: {e}")
|
166
|
-
|
239
|
+
|
167
240
|
# Load configuration from environment variables
|
168
241
|
self._load_env_variables()
|
169
242
|
|
@@ -228,14 +301,14 @@ class Config:
|
|
228
301
|
Configuration value
|
229
302
|
"""
|
230
303
|
parts = key.split(".")
|
231
|
-
|
304
|
+
|
232
305
|
# Get value from config
|
233
306
|
value = self.config_data
|
234
307
|
for part in parts:
|
235
308
|
if not isinstance(value, dict) or part not in value:
|
236
309
|
return default
|
237
310
|
value = value[part]
|
238
|
-
|
311
|
+
|
239
312
|
return value
|
240
313
|
|
241
314
|
def get_all(self) -> Dict[str, Any]:
|
@@ -260,17 +333,17 @@ class Config:
|
|
260
333
|
self.config_data[key] = value
|
261
334
|
else:
|
262
335
|
section = parts[0]
|
263
|
-
|
264
|
-
|
336
|
+
param_key = ".".join(parts[1:])
|
337
|
+
|
265
338
|
if section not in self.config_data:
|
266
339
|
self.config_data[section] = {}
|
267
|
-
|
340
|
+
|
268
341
|
current = self.config_data[section]
|
269
342
|
for part in parts[1:-1]:
|
270
343
|
if part not in current:
|
271
344
|
current[part] = {}
|
272
345
|
current = current[part]
|
273
|
-
|
346
|
+
|
274
347
|
current[parts[-1]] = value
|
275
348
|
|
276
349
|
def save(self, path: Optional[str] = None) -> None:
|
@@ -278,7 +351,8 @@ class Config:
|
|
278
351
|
Save configuration to file.
|
279
352
|
|
280
353
|
Args:
|
281
|
-
path: Path to configuration file. If not specified,
|
354
|
+
path: Path to configuration file. If not specified,
|
355
|
+
self.config_path is used.
|
282
356
|
"""
|
283
357
|
save_path = path or self.config_path
|
284
358
|
with open(save_path, 'w', encoding='utf-8') as f:
|
@@ -302,6 +376,215 @@ class Config:
|
|
302
376
|
d[k] = v
|
303
377
|
return d
|
304
378
|
|
379
|
+
def enable_feature(self, feature: str) -> None:
|
380
|
+
"""
|
381
|
+
Enable a specific feature in the configuration.
|
382
|
+
|
383
|
+
Args:
|
384
|
+
feature: Feature to enable (ssl, auth, roles, proxy_registration,
|
385
|
+
security)
|
386
|
+
"""
|
387
|
+
if feature == "ssl":
|
388
|
+
self.set("ssl.enabled", True)
|
389
|
+
self.set("security.ssl.enabled", True)
|
390
|
+
elif feature == "auth":
|
391
|
+
self.set("security.auth.enabled", True)
|
392
|
+
elif feature == "roles":
|
393
|
+
self.set("security.permissions.enabled", True)
|
394
|
+
self.set("roles.enabled", True)
|
395
|
+
elif feature == "proxy_registration":
|
396
|
+
self.set("proxy_registration.enabled", True)
|
397
|
+
elif feature == "security":
|
398
|
+
self.set("security.enabled", True)
|
399
|
+
elif feature == "rate_limit":
|
400
|
+
self.set("security.rate_limit.enabled", True)
|
401
|
+
elif feature == "certificates":
|
402
|
+
self.set("security.certificates.enabled", True)
|
403
|
+
else:
|
404
|
+
raise ValueError(f"Unknown feature: {feature}")
|
405
|
+
|
406
|
+
def disable_feature(self, feature: str) -> None:
|
407
|
+
"""
|
408
|
+
Disable a specific feature in the configuration.
|
409
|
+
|
410
|
+
Args:
|
411
|
+
feature: Feature to disable (ssl, auth, roles, proxy_registration,
|
412
|
+
security)
|
413
|
+
"""
|
414
|
+
if feature == "ssl":
|
415
|
+
self.set("ssl.enabled", False)
|
416
|
+
self.set("security.ssl.enabled", False)
|
417
|
+
elif feature == "auth":
|
418
|
+
self.set("security.auth.enabled", False)
|
419
|
+
elif feature == "roles":
|
420
|
+
self.set("security.permissions.enabled", False)
|
421
|
+
self.set("roles.enabled", False)
|
422
|
+
elif feature == "proxy_registration":
|
423
|
+
self.set("proxy_registration.enabled", False)
|
424
|
+
elif feature == "security":
|
425
|
+
self.set("security.enabled", False)
|
426
|
+
elif feature == "rate_limit":
|
427
|
+
self.set("security.rate_limit.enabled", False)
|
428
|
+
elif feature == "certificates":
|
429
|
+
self.set("security.certificates.enabled", False)
|
430
|
+
else:
|
431
|
+
raise ValueError(f"Unknown feature: {feature}")
|
432
|
+
|
433
|
+
def is_feature_enabled(self, feature: str) -> bool:
|
434
|
+
"""
|
435
|
+
Check if a specific feature is enabled.
|
436
|
+
|
437
|
+
Args:
|
438
|
+
feature: Feature to check (ssl, auth, roles, proxy_registration,
|
439
|
+
security)
|
440
|
+
|
441
|
+
Returns:
|
442
|
+
True if feature is enabled, False otherwise
|
443
|
+
"""
|
444
|
+
if feature == "ssl":
|
445
|
+
return (self.get("ssl.enabled", False) or
|
446
|
+
self.get("security.ssl.enabled", False))
|
447
|
+
elif feature == "auth":
|
448
|
+
return self.get("security.auth.enabled", False)
|
449
|
+
elif feature == "roles":
|
450
|
+
return (self.get("security.permissions.enabled", False) or
|
451
|
+
self.get("roles.enabled", False))
|
452
|
+
elif feature == "proxy_registration":
|
453
|
+
return self.get("proxy_registration.enabled", False)
|
454
|
+
elif feature == "security":
|
455
|
+
return self.get("security.enabled", False)
|
456
|
+
elif feature == "rate_limit":
|
457
|
+
return self.get("security.rate_limit.enabled", False)
|
458
|
+
elif feature == "certificates":
|
459
|
+
return self.get("security.certificates.enabled", False)
|
460
|
+
else:
|
461
|
+
raise ValueError(f"Unknown feature: {feature}")
|
462
|
+
|
463
|
+
def get_enabled_features(self) -> List[str]:
|
464
|
+
"""
|
465
|
+
Get list of all enabled features.
|
466
|
+
|
467
|
+
Returns:
|
468
|
+
List of enabled feature names
|
469
|
+
"""
|
470
|
+
features = []
|
471
|
+
if self.is_feature_enabled("ssl"):
|
472
|
+
features.append("ssl")
|
473
|
+
if self.is_feature_enabled("auth"):
|
474
|
+
features.append("auth")
|
475
|
+
if self.is_feature_enabled("roles"):
|
476
|
+
features.append("roles")
|
477
|
+
if self.is_feature_enabled("proxy_registration"):
|
478
|
+
features.append("proxy_registration")
|
479
|
+
if self.is_feature_enabled("security"):
|
480
|
+
features.append("security")
|
481
|
+
if self.is_feature_enabled("rate_limit"):
|
482
|
+
features.append("rate_limit")
|
483
|
+
if self.is_feature_enabled("certificates"):
|
484
|
+
features.append("certificates")
|
485
|
+
return features
|
486
|
+
|
487
|
+
def configure_auth_mode(self, mode: str, **kwargs) -> None:
|
488
|
+
"""
|
489
|
+
Configure authentication mode.
|
490
|
+
|
491
|
+
Args:
|
492
|
+
mode: Authentication mode (api_key, jwt, certificate, basic, oauth2)
|
493
|
+
**kwargs: Additional configuration parameters
|
494
|
+
"""
|
495
|
+
if mode == "api_key":
|
496
|
+
self.set("security.auth.methods", ["api_key"])
|
497
|
+
if "api_keys" in kwargs:
|
498
|
+
self.set("security.auth.api_keys", kwargs["api_keys"])
|
499
|
+
elif mode == "jwt":
|
500
|
+
self.set("security.auth.methods", ["jwt"])
|
501
|
+
if "jwt_secret" in kwargs:
|
502
|
+
self.set("security.auth.jwt_secret", kwargs["jwt_secret"])
|
503
|
+
elif mode == "certificate":
|
504
|
+
self.set("security.auth.methods", ["certificate"])
|
505
|
+
self.set("security.auth.certificate_auth", True)
|
506
|
+
elif mode == "basic":
|
507
|
+
self.set("security.auth.methods", ["basic"])
|
508
|
+
self.set("security.auth.basic_auth", True)
|
509
|
+
elif mode == "oauth2":
|
510
|
+
self.set("security.auth.methods", ["oauth2"])
|
511
|
+
if "oauth2_config" in kwargs:
|
512
|
+
self.set("security.auth.oauth2_config", kwargs["oauth2_config"])
|
513
|
+
else:
|
514
|
+
raise ValueError(f"Unknown authentication mode: {mode}")
|
515
|
+
|
516
|
+
def configure_proxy_registration_mode(self, mode: str, **kwargs) -> None:
|
517
|
+
"""
|
518
|
+
Configure proxy registration mode.
|
519
|
+
|
520
|
+
Args:
|
521
|
+
mode: Registration mode (token, certificate, api_key, none)
|
522
|
+
**kwargs: Additional configuration parameters
|
523
|
+
"""
|
524
|
+
if mode == "none":
|
525
|
+
self.set("proxy_registration.enabled", False)
|
526
|
+
else:
|
527
|
+
self.set("proxy_registration.enabled", True)
|
528
|
+
|
529
|
+
if mode == "token":
|
530
|
+
self.set("proxy_registration.auth_method", "token")
|
531
|
+
if "token" in kwargs:
|
532
|
+
self.set("proxy_registration.token.token", kwargs["token"])
|
533
|
+
elif mode == "certificate":
|
534
|
+
self.set("proxy_registration.auth_method", "certificate")
|
535
|
+
if "cert_file" in kwargs:
|
536
|
+
self.set("proxy_registration.certificate.cert_file",
|
537
|
+
kwargs["cert_file"])
|
538
|
+
if "key_file" in kwargs:
|
539
|
+
self.set("proxy_registration.certificate.key_file",
|
540
|
+
kwargs["key_file"])
|
541
|
+
elif mode == "api_key":
|
542
|
+
self.set("proxy_registration.auth_method", "api_key")
|
543
|
+
if "key" in kwargs:
|
544
|
+
self.set("proxy_registration.api_key.key", kwargs["key"])
|
545
|
+
|
546
|
+
def create_minimal_config(self) -> Dict[str, Any]:
|
547
|
+
"""
|
548
|
+
Create minimal configuration with only essential features.
|
549
|
+
|
550
|
+
Returns:
|
551
|
+
Minimal configuration dictionary
|
552
|
+
"""
|
553
|
+
minimal_config = self.config_data.copy()
|
554
|
+
|
555
|
+
# Disable all optional features
|
556
|
+
minimal_config["ssl"]["enabled"] = False
|
557
|
+
minimal_config["security"]["enabled"] = False
|
558
|
+
minimal_config["security"]["auth"]["enabled"] = False
|
559
|
+
minimal_config["security"]["permissions"]["enabled"] = False
|
560
|
+
minimal_config["security"]["rate_limit"]["enabled"] = False
|
561
|
+
minimal_config["security"]["certificates"]["enabled"] = False
|
562
|
+
minimal_config["proxy_registration"]["enabled"] = False
|
563
|
+
minimal_config["roles"]["enabled"] = False
|
564
|
+
|
565
|
+
return minimal_config
|
566
|
+
|
567
|
+
def create_secure_config(self) -> Dict[str, Any]:
|
568
|
+
"""
|
569
|
+
Create secure configuration with all security features enabled.
|
570
|
+
|
571
|
+
Returns:
|
572
|
+
Secure configuration dictionary
|
573
|
+
"""
|
574
|
+
secure_config = self.config_data.copy()
|
575
|
+
|
576
|
+
# Enable all security features
|
577
|
+
secure_config["ssl"]["enabled"] = True
|
578
|
+
secure_config["security"]["enabled"] = True
|
579
|
+
secure_config["security"]["auth"]["enabled"] = True
|
580
|
+
secure_config["security"]["permissions"]["enabled"] = True
|
581
|
+
secure_config["security"]["rate_limit"]["enabled"] = True
|
582
|
+
secure_config["security"]["certificates"]["enabled"] = True
|
583
|
+
secure_config["proxy_registration"]["enabled"] = True
|
584
|
+
secure_config["roles"]["enabled"] = True
|
585
|
+
|
586
|
+
return secure_config
|
587
|
+
|
305
588
|
|
306
589
|
# Singleton instance
|
307
590
|
config = Config()
|