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.

Files changed (269) hide show
  1. mcp_proxy_adapter/__init__.py +47 -0
  2. mcp_proxy_adapter/__main__.py +13 -0
  3. mcp_proxy_adapter/api/__init__.py +0 -0
  4. mcp_proxy_adapter/api/app.py +66 -0
  5. mcp_proxy_adapter/api/core/__init__.py +18 -0
  6. mcp_proxy_adapter/api/core/app_factory.py +400 -0
  7. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  8. mcp_proxy_adapter/api/core/registration_context.py +356 -0
  9. mcp_proxy_adapter/api/core/registration_manager.py +307 -0
  10. mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
  11. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  12. mcp_proxy_adapter/api/handlers.py +181 -0
  13. mcp_proxy_adapter/api/middleware/__init__.py +21 -0
  14. mcp_proxy_adapter/api/middleware/base.py +54 -0
  15. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
  16. mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
  17. mcp_proxy_adapter/api/middleware/factory.py +147 -0
  18. mcp_proxy_adapter/api/middleware/logging.py +31 -0
  19. mcp_proxy_adapter/api/middleware/performance.py +51 -0
  20. mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
  21. mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
  22. mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
  23. mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
  24. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  25. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  26. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  27. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  28. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  29. mcp_proxy_adapter/api/schemas.py +270 -0
  30. mcp_proxy_adapter/api/tool_integration.py +131 -0
  31. mcp_proxy_adapter/api/tools.py +163 -0
  32. mcp_proxy_adapter/cli/__init__.py +12 -0
  33. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  34. mcp_proxy_adapter/cli/commands/client.py +100 -0
  35. mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
  36. mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
  37. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  38. mcp_proxy_adapter/cli/commands/server.py +174 -0
  39. mcp_proxy_adapter/cli/commands/sets.py +132 -0
  40. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  41. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  42. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  43. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  44. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  45. mcp_proxy_adapter/cli/main.py +63 -0
  46. mcp_proxy_adapter/cli/parser.py +338 -0
  47. mcp_proxy_adapter/cli/validators.py +231 -0
  48. mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
  49. mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
  50. mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
  51. mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
  52. mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
  53. mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
  54. mcp_proxy_adapter/client/proxy.py +123 -0
  55. mcp_proxy_adapter/commands/__init__.py +66 -0
  56. mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
  57. mcp_proxy_adapter/commands/base.py +389 -0
  58. mcp_proxy_adapter/commands/builtin_commands.py +30 -0
  59. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  60. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  61. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  62. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  63. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  64. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  65. mcp_proxy_adapter/commands/catalog_manager.py +97 -0
  66. mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
  67. mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
  68. mcp_proxy_adapter/commands/command_registry.py +298 -0
  69. mcp_proxy_adapter/commands/config_command.py +102 -0
  70. mcp_proxy_adapter/commands/dependency_container.py +40 -0
  71. mcp_proxy_adapter/commands/dependency_manager.py +143 -0
  72. mcp_proxy_adapter/commands/echo_command.py +48 -0
  73. mcp_proxy_adapter/commands/health_command.py +142 -0
  74. mcp_proxy_adapter/commands/help_command.py +175 -0
  75. mcp_proxy_adapter/commands/hooks.py +172 -0
  76. mcp_proxy_adapter/commands/key_management_command.py +484 -0
  77. mcp_proxy_adapter/commands/load_command.py +123 -0
  78. mcp_proxy_adapter/commands/plugins_command.py +246 -0
  79. mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
  80. mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
  81. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  82. mcp_proxy_adapter/commands/registration_status_command.py +76 -0
  83. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  84. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  85. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  86. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  87. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  88. mcp_proxy_adapter/commands/reload_command.py +136 -0
  89. mcp_proxy_adapter/commands/result.py +157 -0
  90. mcp_proxy_adapter/commands/role_test_command.py +99 -0
  91. mcp_proxy_adapter/commands/roles_management_command.py +502 -0
  92. mcp_proxy_adapter/commands/security_command.py +472 -0
  93. mcp_proxy_adapter/commands/settings_command.py +113 -0
  94. mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
  95. mcp_proxy_adapter/commands/token_management_command.py +500 -0
  96. mcp_proxy_adapter/commands/transport_management_command.py +129 -0
  97. mcp_proxy_adapter/commands/unload_command.py +92 -0
  98. mcp_proxy_adapter/config.py +32 -0
  99. mcp_proxy_adapter/core/__init__.py +8 -0
  100. mcp_proxy_adapter/core/app_factory.py +560 -0
  101. mcp_proxy_adapter/core/app_runner.py +318 -0
  102. mcp_proxy_adapter/core/auth_validator.py +508 -0
  103. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  104. mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
  105. mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
  106. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  107. mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
  108. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
  109. mcp_proxy_adapter/core/certificate_utils.py +249 -0
  110. mcp_proxy_adapter/core/client.py +608 -0
  111. mcp_proxy_adapter/core/client_manager.py +271 -0
  112. mcp_proxy_adapter/core/client_security.py +411 -0
  113. mcp_proxy_adapter/core/config/__init__.py +18 -0
  114. mcp_proxy_adapter/core/config/config.py +237 -0
  115. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  116. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  117. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  118. mcp_proxy_adapter/core/config/simple_config.py +204 -0
  119. mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
  120. mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
  121. mcp_proxy_adapter/core/config_converter.py +252 -0
  122. mcp_proxy_adapter/core/config_validator.py +211 -0
  123. mcp_proxy_adapter/core/crl_utils.py +362 -0
  124. mcp_proxy_adapter/core/errors.py +276 -0
  125. mcp_proxy_adapter/core/job_manager.py +54 -0
  126. mcp_proxy_adapter/core/logging.py +250 -0
  127. mcp_proxy_adapter/core/mtls_asgi.py +140 -0
  128. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  129. mcp_proxy_adapter/core/mtls_proxy.py +229 -0
  130. mcp_proxy_adapter/core/mtls_server.py +154 -0
  131. mcp_proxy_adapter/core/protocol_manager.py +232 -0
  132. mcp_proxy_adapter/core/proxy/__init__.py +19 -0
  133. mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
  134. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
  135. mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
  136. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  137. mcp_proxy_adapter/core/proxy_client.py +184 -0
  138. mcp_proxy_adapter/core/proxy_registration.py +80 -0
  139. mcp_proxy_adapter/core/role_utils.py +103 -0
  140. mcp_proxy_adapter/core/security_adapter.py +343 -0
  141. mcp_proxy_adapter/core/security_factory.py +96 -0
  142. mcp_proxy_adapter/core/security_integration.py +342 -0
  143. mcp_proxy_adapter/core/server_adapter.py +251 -0
  144. mcp_proxy_adapter/core/server_engine.py +217 -0
  145. mcp_proxy_adapter/core/settings.py +260 -0
  146. mcp_proxy_adapter/core/signal_handler.py +107 -0
  147. mcp_proxy_adapter/core/ssl_utils.py +161 -0
  148. mcp_proxy_adapter/core/transport_manager.py +153 -0
  149. mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
  150. mcp_proxy_adapter/core/utils.py +101 -0
  151. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  152. mcp_proxy_adapter/core/validation/config_validator.py +219 -0
  153. mcp_proxy_adapter/core/validation/file_validator.py +131 -0
  154. mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
  155. mcp_proxy_adapter/core/validation/security_validator.py +140 -0
  156. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  157. mcp_proxy_adapter/custom_openapi.py +58 -0
  158. mcp_proxy_adapter/examples/__init__.py +16 -0
  159. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  160. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  161. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  162. mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
  163. mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
  164. mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
  165. mcp_proxy_adapter/examples/check_config.py +413 -0
  166. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  167. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  168. mcp_proxy_adapter/examples/config_builder.py +234 -0
  169. mcp_proxy_adapter/examples/config_cli.py +282 -0
  170. mcp_proxy_adapter/examples/create_test_configs.py +174 -0
  171. mcp_proxy_adapter/examples/debug_request_state.py +130 -0
  172. mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
  173. mcp_proxy_adapter/examples/demo_client.py +287 -0
  174. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  175. mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
  176. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
  177. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
  178. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
  179. mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
  180. mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
  181. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
  182. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
  183. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
  184. mcp_proxy_adapter/examples/full_application/main.py +311 -0
  185. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
  186. mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
  187. mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
  188. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
  189. mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
  190. mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
  191. mcp_proxy_adapter/examples/generate_config.py +502 -0
  192. mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
  193. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  194. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  195. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  196. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  197. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  198. mcp_proxy_adapter/examples/required_certificates.py +208 -0
  199. mcp_proxy_adapter/examples/run_example.py +77 -0
  200. mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
  201. mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
  202. mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
  203. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  204. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  205. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  206. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  207. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  208. mcp_proxy_adapter/examples/security_test_client.py +72 -0
  209. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  210. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  211. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  212. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  213. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  214. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  215. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  216. mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
  217. mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
  218. mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
  219. mcp_proxy_adapter/examples/test_config.py +205 -0
  220. mcp_proxy_adapter/examples/test_config_builder.py +110 -0
  221. mcp_proxy_adapter/examples/test_examples.py +308 -0
  222. mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
  223. mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
  224. mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
  225. mcp_proxy_adapter/examples/universal_client.py +674 -0
  226. mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
  227. mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
  228. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
  229. mcp_proxy_adapter/integrations/__init__.py +25 -0
  230. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  231. mcp_proxy_adapter/main.py +311 -0
  232. mcp_proxy_adapter/openapi.py +375 -0
  233. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  234. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  235. mcp_proxy_adapter/schemas/roles.json +37 -0
  236. mcp_proxy_adapter/schemas/roles_schema.json +162 -0
  237. mcp_proxy_adapter/version.py +5 -0
  238. mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
  239. mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
  240. {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
  241. mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
  242. mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
  243. adapters/__init__.py +0 -16
  244. analyzers/__init__.py +0 -14
  245. analyzers/docstring_analyzer.py +0 -199
  246. analyzers/type_analyzer.py +0 -151
  247. cli/__init__.py +0 -12
  248. cli/__main__.py +0 -79
  249. cli/command_runner.py +0 -233
  250. dispatchers/__init__.py +0 -14
  251. dispatchers/base_dispatcher.py +0 -85
  252. dispatchers/json_rpc_dispatcher.py +0 -198
  253. generators/__init__.py +0 -14
  254. generators/endpoint_generator.py +0 -172
  255. generators/openapi_generator.py +0 -254
  256. generators/rest_api_generator.py +0 -207
  257. mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
  258. mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
  259. mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
  260. mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
  261. openapi_schema/__init__.py +0 -38
  262. openapi_schema/command_registry.py +0 -312
  263. openapi_schema/rest_schema.py +0 -510
  264. openapi_schema/rpc_generator.py +0 -307
  265. openapi_schema/rpc_schema.py +0 -416
  266. validators/__init__.py +0 -14
  267. validators/base_validator.py +0 -23
  268. validators/docstring_validator.py +0 -75
  269. validators/metadata_validator.py +0 -76
@@ -0,0 +1,562 @@
1
+ """
2
+ Certificate Management Command
3
+
4
+ This module provides commands for certificate management including creation,
5
+ validation, revocation, and information retrieval.
6
+
7
+ Author: MCP Proxy Adapter Team
8
+ Version: 1.0.0
9
+ """
10
+
11
+ import logging
12
+ import os
13
+ from typing import Dict, List, Optional, Any
14
+ from pathlib import Path
15
+
16
+ from .base import Command
17
+ from .result import CommandResult, SuccessResult, ErrorResult
18
+ from ..core.certificate_utils import CertificateUtils
19
+ from ..core.auth_validator import AuthValidator
20
+ from ..core.role_utils import RoleUtils
21
+
22
+ from mcp_proxy_adapter.core.logging import get_global_logger
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class CertificateResult:
27
+ """
28
+ Result class for certificate operations.
29
+
30
+ Contains certificate information and operation status.
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ cert_path: str,
36
+ cert_type: str,
37
+ common_name: str,
38
+ roles: Optional[List[str]] = None,
39
+ expiry_date: Optional[str] = None,
40
+ serial_number: Optional[str] = None,
41
+ status: str = "valid",
42
+ error: Optional[str] = None,
43
+ ):
44
+ """
45
+ Initialize certificate result.
46
+
47
+ Args:
48
+ cert_path: Path to certificate file
49
+ cert_type: Type of certificate (CA, server, client)
50
+ common_name: Common name of the certificate
51
+ roles: List of roles assigned to certificate
52
+ expiry_date: Certificate expiry date
53
+ serial_number: Certificate serial number
54
+ status: Certificate status (valid, expired, revoked, error)
55
+ error: Error message if any
56
+ """
57
+ self.cert_path = cert_path
58
+ self.cert_type = cert_type
59
+ self.common_name = common_name
60
+ self.roles = roles or []
61
+ self.expiry_date = expiry_date
62
+ self.serial_number = serial_number
63
+ self.status = status
64
+ self.error = error
65
+
66
+ def to_dict(self) -> Dict[str, Any]:
67
+ """
68
+ Convert to dictionary format.
69
+
70
+ Returns:
71
+ Dictionary representation
72
+ """
73
+ return {
74
+ "cert_path": self.cert_path,
75
+ "cert_type": self.cert_type,
76
+ "common_name": self.common_name,
77
+ "roles": self.roles,
78
+ "expiry_date": self.expiry_date,
79
+ "serial_number": self.serial_number,
80
+ "status": self.status,
81
+ "error": self.error,
82
+ }
83
+
84
+ @classmethod
85
+
86
+
87
+ class CertificateManagementCommand(Command):
88
+ """
89
+ Command for certificate management.
90
+
91
+ Provides methods for creating, managing, and validating certificates.
92
+ """
93
+
94
+ # Command metadata
95
+ name = "certificate_management"
96
+ version = "1.0.0"
97
+ descr = "Certificate creation, validation, and management"
98
+ category = "security"
99
+ author = "MCP Proxy Adapter Team"
100
+ email = "team@mcp-proxy-adapter.com"
101
+ source_url = "https://github.com/mcp-proxy-adapter"
102
+ result_class = CertificateResult
103
+
104
+ def __init__(self):
105
+ """Initialize certificate management command."""
106
+ super().__init__()
107
+ self.certificate_utils = CertificateUtils()
108
+ self.auth_validator = AuthValidator()
109
+ self.role_utils = RoleUtils()
110
+
111
+ async def execute(self, **kwargs) -> CommandResult:
112
+ """
113
+ Execute certificate management command.
114
+
115
+ Args:
116
+ **kwargs: Command parameters including:
117
+ - action: Action to perform (cert_create_ca, cert_create_server, cert_create_client, cert_revoke, cert_list, cert_info)
118
+ - common_name: Common name for certificate creation
119
+ - roles: List of roles for certificate creation
120
+ - ca_cert_path: CA certificate path for server/client certificate creation
121
+ - ca_key_path: CA key path for server/client certificate creation
122
+ - output_dir: Output directory for certificate creation
123
+ - validity_days: Certificate validity period in days
124
+ - key_size: Key size in bits for CA certificate creation
125
+ - cert_path: Certificate path for revocation and info
126
+ - cert_dir: Directory for certificate listing
127
+
128
+ Returns:
129
+ CommandResult with certificate operation status
130
+ """
131
+ action = kwargs.get("action", "cert_list")
132
+
133
+ if action == "cert_create_ca":
134
+ common_name = kwargs.get("common_name")
135
+ output_dir = kwargs.get("output_dir")
136
+ validity_days = kwargs.get("validity_days", 365)
137
+ key_size = kwargs.get("key_size", 2048)
138
+ return await self.cert_create_ca(
139
+ common_name, output_dir, validity_days, key_size
140
+ )
141
+ elif action == "cert_create_server":
142
+ common_name = kwargs.get("common_name")
143
+ roles = kwargs.get("roles", [])
144
+ ca_cert_path = kwargs.get("ca_cert_path")
145
+ ca_key_path = kwargs.get("ca_key_path")
146
+ output_dir = kwargs.get("output_dir")
147
+ validity_days = kwargs.get("validity_days", 365)
148
+ return await self.cert_create_server(
149
+ common_name, roles, ca_cert_path, ca_key_path, output_dir, validity_days
150
+ )
151
+ elif action == "cert_create_client":
152
+ common_name = kwargs.get("common_name")
153
+ roles = kwargs.get("roles", [])
154
+ ca_cert_path = kwargs.get("ca_cert_path")
155
+ ca_key_path = kwargs.get("ca_key_path")
156
+ output_dir = kwargs.get("output_dir")
157
+ validity_days = kwargs.get("validity_days", 365)
158
+ return await self.cert_create_client(
159
+ common_name, roles, ca_cert_path, ca_key_path, output_dir, validity_days
160
+ )
161
+ elif action == "cert_revoke":
162
+ cert_path = kwargs.get("cert_path")
163
+ return await self.cert_revoke(cert_path)
164
+ elif action == "cert_list":
165
+ cert_dir = kwargs.get("cert_dir", "/tmp")
166
+ return await self.cert_list(cert_dir)
167
+ elif action == "cert_info":
168
+ cert_path = kwargs.get("cert_path")
169
+ return await self.cert_info(cert_path)
170
+ else:
171
+ return ErrorResult(
172
+ message=f"Unknown action: {action}. Supported actions: cert_create_ca, cert_create_server, cert_create_client, cert_revoke, cert_list, cert_info"
173
+ )
174
+
175
+ async def cert_create_ca(
176
+ self,
177
+ common_name: str,
178
+ output_dir: str,
179
+ validity_days: int = 365,
180
+ key_size: int = 2048,
181
+ ) -> CommandResult:
182
+ """
183
+ Create a CA certificate and private key.
184
+
185
+ Args:
186
+ common_name: Common name for the CA certificate
187
+ output_dir: Directory to save certificate and key files
188
+ validity_days: Certificate validity period in days
189
+ key_size: RSA key size in bits
190
+
191
+ Returns:
192
+ CommandResult with CA certificate creation status
193
+ """
194
+ try:
195
+ get_global_logger().info(f"Creating CA certificate: {common_name}")
196
+
197
+ # Validate parameters
198
+ if not common_name or not common_name.strip():
199
+ return ErrorResult(message="Common name cannot be empty")
200
+
201
+ if validity_days <= 0:
202
+ return ErrorResult(message="Validity days must be positive")
203
+
204
+ if key_size < 1024:
205
+ return ErrorResult(message="Key size must be at least 1024 bits")
206
+
207
+ # Create CA certificate
208
+ result = self.certificate_utils.create_ca_certificate(
209
+ common_name, output_dir, validity_days, key_size
210
+ )
211
+
212
+ # Validate created certificate (CA certificates don't need server validation)
213
+ cert_path = result.get("cert_path")
214
+ if cert_path and os.path.exists(cert_path):
215
+ # For CA certificates, we only check if the file exists and is readable
216
+ try:
217
+ with open(cert_path, "rb") as f:
218
+ cert_data = f.read()
219
+ if not cert_data:
220
+ return ErrorResult(
221
+ message="Created CA certificate file is empty"
222
+ )
223
+ except Exception as e:
224
+ return ErrorResult(
225
+ message=f"Created CA certificate file is not readable: {str(e)}"
226
+ )
227
+
228
+ cert_result = CertificateResult(
229
+ cert_path=result.get("cert_path", ""),
230
+ cert_type="CA",
231
+ common_name=common_name,
232
+ status="valid",
233
+ )
234
+
235
+ get_global_logger().info(
236
+ f"CA certificate created successfully: {result.get('cert_path')}"
237
+ )
238
+ return SuccessResult(
239
+ data={"certificate": cert_result.to_dict(), "files": result}
240
+ )
241
+
242
+ except Exception as e:
243
+ get_global_logger().error(f"CA certificate creation failed: {e}")
244
+ return ErrorResult(message=f"CA certificate creation failed: {str(e)}")
245
+
246
+ async def cert_create_server(
247
+ self,
248
+ common_name: str,
249
+ roles: List[str],
250
+ ca_cert_path: str,
251
+ ca_key_path: str,
252
+ output_dir: str,
253
+ validity_days: int = 365,
254
+ ) -> CommandResult:
255
+ """
256
+ Create a server certificate signed by CA.
257
+
258
+ Args:
259
+ common_name: Common name for the server certificate
260
+ roles: List of roles to assign to the certificate
261
+ ca_cert_path: Path to CA certificate file
262
+ ca_key_path: Path to CA private key file
263
+ output_dir: Directory to save certificate and key files
264
+ validity_days: Certificate validity period in days
265
+
266
+ Returns:
267
+ CommandResult with server certificate creation status
268
+ """
269
+ try:
270
+ get_global_logger().info(f"Creating server certificate: {common_name}")
271
+
272
+ # Validate parameters
273
+ if not common_name or not common_name.strip():
274
+ return ErrorResult(message="Common name cannot be empty")
275
+
276
+ if not roles:
277
+ return ErrorResult(message="At least one role must be specified")
278
+
279
+ # Validate roles
280
+ if not self.role_utils.validate_roles(roles):
281
+ return ErrorResult(message="Invalid roles specified")
282
+
283
+ # Check CA files
284
+ if not os.path.exists(ca_cert_path):
285
+ return ErrorResult(message=f"CA certificate not found: {ca_cert_path}")
286
+
287
+ if not os.path.exists(ca_key_path):
288
+ return ErrorResult(message=f"CA private key not found: {ca_key_path}")
289
+
290
+ # Create server certificate
291
+ result = self.certificate_utils.create_server_certificate(
292
+ common_name, roles, ca_cert_path, ca_key_path, output_dir, validity_days
293
+ )
294
+
295
+ # Validate created certificate
296
+ cert_path = result.get("cert_path")
297
+ if cert_path and os.path.exists(cert_path):
298
+ validation = self.auth_validator.validate_certificate(cert_path)
299
+ if not validation.is_valid:
300
+ return ErrorResult(
301
+ message=f"Created server certificate validation failed: {validation.error_message}"
302
+ )
303
+
304
+ cert_result = CertificateResult(
305
+ cert_path=result.get("cert_path", ""),
306
+ cert_type="server",
307
+ common_name=common_name,
308
+ roles=roles,
309
+ status="valid",
310
+ )
311
+
312
+ get_global_logger().info(
313
+ f"Server certificate created successfully: {result.get('cert_path')}"
314
+ )
315
+ return SuccessResult(
316
+ data={"certificate": cert_result.to_dict(), "files": result}
317
+ )
318
+
319
+ except Exception as e:
320
+ get_global_logger().error(f"Server certificate creation failed: {e}")
321
+ return ErrorResult(message=f"Server certificate creation failed: {str(e)}")
322
+
323
+ async def cert_create_client(
324
+ self,
325
+ common_name: str,
326
+ roles: List[str],
327
+ ca_cert_path: str,
328
+ ca_key_path: str,
329
+ output_dir: str,
330
+ validity_days: int = 365,
331
+ ) -> CommandResult:
332
+ """
333
+ Create a client certificate signed by CA.
334
+
335
+ Args:
336
+ common_name: Common name for the client certificate
337
+ roles: List of roles to assign to the certificate
338
+ ca_cert_path: Path to CA certificate file
339
+ ca_key_path: Path to CA private key file
340
+ output_dir: Directory to save certificate and key files
341
+ validity_days: Certificate validity period in days
342
+
343
+ Returns:
344
+ CommandResult with client certificate creation status
345
+ """
346
+ try:
347
+ get_global_logger().info(f"Creating client certificate: {common_name}")
348
+
349
+ # Validate parameters
350
+ if not common_name or not common_name.strip():
351
+ return ErrorResult(message="Common name cannot be empty")
352
+
353
+ if not roles:
354
+ return ErrorResult(message="At least one role must be specified")
355
+
356
+ # Validate roles
357
+ if not self.role_utils.validate_roles(roles):
358
+ return ErrorResult(message="Invalid roles specified")
359
+
360
+ # Check CA files
361
+ if not os.path.exists(ca_cert_path):
362
+ return ErrorResult(message=f"CA certificate not found: {ca_cert_path}")
363
+
364
+ if not os.path.exists(ca_key_path):
365
+ return ErrorResult(message=f"CA private key not found: {ca_key_path}")
366
+
367
+ # Create client certificate
368
+ result = self.certificate_utils.create_client_certificate(
369
+ common_name, roles, ca_cert_path, ca_key_path, output_dir, validity_days
370
+ )
371
+
372
+ # Validate created certificate
373
+ cert_path = result.get("cert_path")
374
+ if cert_path and os.path.exists(cert_path):
375
+ validation = self.auth_validator.validate_certificate(cert_path)
376
+ if not validation.is_valid:
377
+ return ErrorResult(
378
+ message=f"Created client certificate validation failed: {validation.error_message}"
379
+ )
380
+
381
+ cert_result = CertificateResult(
382
+ cert_path=result.get("cert_path", ""),
383
+ cert_type="client",
384
+ common_name=common_name,
385
+ roles=roles,
386
+ status="valid",
387
+ )
388
+
389
+ get_global_logger().info(
390
+ f"Client certificate created successfully: {result.get('cert_path')}"
391
+ )
392
+ return SuccessResult(
393
+ data={"certificate": cert_result.to_dict(), "files": result}
394
+ )
395
+
396
+ except Exception as e:
397
+ get_global_logger().error(f"Client certificate creation failed: {e}")
398
+ return ErrorResult(message=f"Client certificate creation failed: {str(e)}")
399
+
400
+ async def cert_revoke(self, cert_path: str) -> CommandResult:
401
+ """
402
+ Revoke a certificate.
403
+
404
+ Args:
405
+ cert_path: Path to certificate file to revoke
406
+
407
+ Returns:
408
+ CommandResult with revocation status
409
+ """
410
+ try:
411
+ get_global_logger().info(f"Revoking certificate: {cert_path}")
412
+
413
+ # Validate parameters
414
+ if not cert_path or not os.path.exists(cert_path):
415
+ return ErrorResult(message=f"Certificate file not found: {cert_path}")
416
+
417
+ # Get certificate info before revocation
418
+ cert_info = self.certificate_utils.get_certificate_info(cert_path)
419
+ if not cert_info:
420
+ return ErrorResult(message="Could not read certificate information")
421
+
422
+ # Revoke certificate
423
+ result = self.certificate_utils.revoke_certificate(cert_path)
424
+
425
+ cert_result = CertificateResult(
426
+ cert_path=cert_path,
427
+ cert_type=cert_info.get("type", "unknown"),
428
+ common_name=cert_info.get("common_name", ""),
429
+ roles=cert_info.get("roles", []),
430
+ serial_number=cert_info.get("serial_number"),
431
+ status="revoked",
432
+ )
433
+
434
+ get_global_logger().info(f"Certificate revoked successfully: {cert_path}")
435
+ return SuccessResult(
436
+ data={"certificate": cert_result.to_dict(), "revocation_result": result}
437
+ )
438
+
439
+ except Exception as e:
440
+ get_global_logger().error(f"Certificate revocation failed: {e}")
441
+ return ErrorResult(message=f"Certificate revocation failed: {str(e)}")
442
+
443
+ async def cert_list(self, cert_dir: str) -> CommandResult:
444
+ """
445
+ List all certificates in a directory.
446
+
447
+ Args:
448
+ cert_dir: Directory to scan for certificates
449
+
450
+ Returns:
451
+ CommandResult with list of certificates
452
+ """
453
+ try:
454
+ get_global_logger().info(f"Listing certificates in directory: {cert_dir}")
455
+
456
+ # Validate parameters
457
+ if not cert_dir or not os.path.exists(cert_dir):
458
+ return ErrorResult(message=f"Directory not found: {cert_dir}")
459
+
460
+ if not os.path.isdir(cert_dir):
461
+ return ErrorResult(message=f"Path is not a directory: {cert_dir}")
462
+
463
+ # List certificates
464
+ certificates = []
465
+ cert_extensions = [".crt", ".pem", ".cer", ".der"]
466
+
467
+ for file_path in Path(cert_dir).rglob("*"):
468
+ if file_path.is_file() and file_path.suffix.lower() in cert_extensions:
469
+ try:
470
+ cert_info = self.certificate_utils.get_certificate_info(
471
+ str(file_path)
472
+ )
473
+ if cert_info:
474
+ cert_result = CertificateResult(
475
+ cert_path=str(file_path),
476
+ cert_type=cert_info.get("type", "unknown"),
477
+ common_name=cert_info.get("common_name", ""),
478
+ roles=cert_info.get("roles", []),
479
+ expiry_date=cert_info.get("expiry_date"),
480
+ serial_number=cert_info.get("serial_number"),
481
+ status=cert_info.get("status", "valid"),
482
+ )
483
+ certificates.append(cert_result.to_dict())
484
+ except Exception as e:
485
+ get_global_logger().warning(f"Could not read certificate {file_path}: {e}")
486
+ # Add certificate with error status
487
+ cert_result = CertificateResult(
488
+ cert_path=str(file_path),
489
+ cert_type="unknown",
490
+ common_name="",
491
+ status="error",
492
+ error=str(e),
493
+ )
494
+ certificates.append(cert_result.to_dict())
495
+
496
+ get_global_logger().info(f"Found {len(certificates)} certificates in {cert_dir}")
497
+ return SuccessResult(
498
+ data={
499
+ "certificates": certificates,
500
+ "total_count": len(certificates),
501
+ "directory": cert_dir,
502
+ }
503
+ )
504
+
505
+ except Exception as e:
506
+ get_global_logger().error(f"Certificate listing failed: {e}")
507
+ return ErrorResult(message=f"Certificate listing failed: {str(e)}")
508
+
509
+ async def cert_info(self, cert_path: str) -> CommandResult:
510
+ """
511
+ Get detailed information about a certificate.
512
+
513
+ Args:
514
+ cert_path: Path to certificate file
515
+
516
+ Returns:
517
+ CommandResult with certificate information
518
+ """
519
+ try:
520
+ get_global_logger().info(f"Getting certificate info: {cert_path}")
521
+
522
+ # Validate parameters
523
+ if not cert_path or not os.path.exists(cert_path):
524
+ return ErrorResult(message=f"Certificate file not found: {cert_path}")
525
+
526
+ # Get certificate information
527
+ cert_info = self.certificate_utils.get_certificate_info(cert_path)
528
+ if not cert_info:
529
+ return ErrorResult(message="Could not read certificate information")
530
+
531
+ # Validate certificate
532
+ validation = self.auth_validator.validate_certificate(cert_path)
533
+ status = "valid" if validation.is_valid else "error"
534
+
535
+ cert_result = CertificateResult(
536
+ cert_path=cert_path,
537
+ cert_type=cert_info.get("type", "unknown"),
538
+ common_name=cert_info.get("common_name", ""),
539
+ roles=cert_info.get("roles", []),
540
+ expiry_date=cert_info.get("expiry_date"),
541
+ serial_number=cert_info.get("serial_number"),
542
+ status=status,
543
+ error=None if validation.is_valid else validation.error_message,
544
+ )
545
+
546
+ get_global_logger().info(f"Certificate info retrieved successfully: {cert_path}")
547
+ return SuccessResult(
548
+ data={
549
+ "certificate": cert_result.to_dict(),
550
+ "validation": {
551
+ "is_valid": validation.is_valid,
552
+ "error_code": validation.error_code,
553
+ "error_message": validation.error_message,
554
+ "roles": validation.roles,
555
+ },
556
+ "details": cert_info,
557
+ }
558
+ )
559
+
560
+ except Exception as e:
561
+ get_global_logger().error(f"Certificate info retrieval failed: {e}")
562
+ return ErrorResult(message=f"Certificate info retrieval failed: {str(e)}")