mcp-proxy-adapter 6.3.3__py3-none-any.whl → 6.3.5__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.
Files changed (129) hide show
  1. mcp_proxy_adapter/__init__.py +9 -5
  2. mcp_proxy_adapter/__main__.py +1 -1
  3. mcp_proxy_adapter/api/app.py +227 -176
  4. mcp_proxy_adapter/api/handlers.py +68 -60
  5. mcp_proxy_adapter/api/middleware/__init__.py +7 -5
  6. mcp_proxy_adapter/api/middleware/base.py +19 -16
  7. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +44 -34
  8. mcp_proxy_adapter/api/middleware/error_handling.py +57 -67
  9. mcp_proxy_adapter/api/middleware/factory.py +50 -52
  10. mcp_proxy_adapter/api/middleware/logging.py +46 -30
  11. mcp_proxy_adapter/api/middleware/performance.py +19 -16
  12. mcp_proxy_adapter/api/middleware/protocol_middleware.py +80 -50
  13. mcp_proxy_adapter/api/middleware/transport_middleware.py +26 -24
  14. mcp_proxy_adapter/api/middleware/unified_security.py +70 -51
  15. mcp_proxy_adapter/api/middleware/user_info_middleware.py +43 -34
  16. mcp_proxy_adapter/api/schemas.py +69 -43
  17. mcp_proxy_adapter/api/tool_integration.py +83 -63
  18. mcp_proxy_adapter/api/tools.py +60 -50
  19. mcp_proxy_adapter/commands/__init__.py +15 -6
  20. mcp_proxy_adapter/commands/auth_validation_command.py +107 -110
  21. mcp_proxy_adapter/commands/base.py +108 -112
  22. mcp_proxy_adapter/commands/builtin_commands.py +28 -18
  23. mcp_proxy_adapter/commands/catalog_manager.py +394 -265
  24. mcp_proxy_adapter/commands/cert_monitor_command.py +222 -204
  25. mcp_proxy_adapter/commands/certificate_management_command.py +210 -213
  26. mcp_proxy_adapter/commands/command_registry.py +275 -226
  27. mcp_proxy_adapter/commands/config_command.py +48 -33
  28. mcp_proxy_adapter/commands/dependency_container.py +22 -23
  29. mcp_proxy_adapter/commands/dependency_manager.py +65 -56
  30. mcp_proxy_adapter/commands/echo_command.py +15 -15
  31. mcp_proxy_adapter/commands/health_command.py +31 -29
  32. mcp_proxy_adapter/commands/help_command.py +97 -61
  33. mcp_proxy_adapter/commands/hooks.py +65 -49
  34. mcp_proxy_adapter/commands/key_management_command.py +148 -147
  35. mcp_proxy_adapter/commands/load_command.py +58 -40
  36. mcp_proxy_adapter/commands/plugins_command.py +80 -54
  37. mcp_proxy_adapter/commands/protocol_management_command.py +60 -48
  38. mcp_proxy_adapter/commands/proxy_registration_command.py +107 -115
  39. mcp_proxy_adapter/commands/reload_command.py +43 -37
  40. mcp_proxy_adapter/commands/result.py +26 -33
  41. mcp_proxy_adapter/commands/role_test_command.py +26 -26
  42. mcp_proxy_adapter/commands/roles_management_command.py +176 -173
  43. mcp_proxy_adapter/commands/security_command.py +134 -122
  44. mcp_proxy_adapter/commands/settings_command.py +47 -56
  45. mcp_proxy_adapter/commands/ssl_setup_command.py +109 -129
  46. mcp_proxy_adapter/commands/token_management_command.py +129 -158
  47. mcp_proxy_adapter/commands/transport_management_command.py +41 -36
  48. mcp_proxy_adapter/commands/unload_command.py +42 -37
  49. mcp_proxy_adapter/config.py +36 -35
  50. mcp_proxy_adapter/core/__init__.py +19 -21
  51. mcp_proxy_adapter/core/app_factory.py +30 -9
  52. mcp_proxy_adapter/core/app_runner.py +81 -64
  53. mcp_proxy_adapter/core/auth_validator.py +176 -182
  54. mcp_proxy_adapter/core/certificate_utils.py +469 -426
  55. mcp_proxy_adapter/core/client.py +155 -126
  56. mcp_proxy_adapter/core/client_manager.py +60 -54
  57. mcp_proxy_adapter/core/client_security.py +108 -88
  58. mcp_proxy_adapter/core/config_converter.py +176 -143
  59. mcp_proxy_adapter/core/config_validator.py +12 -4
  60. mcp_proxy_adapter/core/crl_utils.py +21 -7
  61. mcp_proxy_adapter/core/errors.py +64 -20
  62. mcp_proxy_adapter/core/logging.py +34 -29
  63. mcp_proxy_adapter/core/mtls_asgi.py +29 -25
  64. mcp_proxy_adapter/core/mtls_asgi_app.py +66 -54
  65. mcp_proxy_adapter/core/protocol_manager.py +154 -104
  66. mcp_proxy_adapter/core/proxy_client.py +202 -144
  67. mcp_proxy_adapter/core/proxy_registration.py +12 -2
  68. mcp_proxy_adapter/core/role_utils.py +139 -125
  69. mcp_proxy_adapter/core/security_adapter.py +88 -77
  70. mcp_proxy_adapter/core/security_factory.py +50 -44
  71. mcp_proxy_adapter/core/security_integration.py +72 -24
  72. mcp_proxy_adapter/core/server_adapter.py +68 -64
  73. mcp_proxy_adapter/core/server_engine.py +71 -53
  74. mcp_proxy_adapter/core/settings.py +68 -58
  75. mcp_proxy_adapter/core/ssl_utils.py +69 -56
  76. mcp_proxy_adapter/core/transport_manager.py +72 -60
  77. mcp_proxy_adapter/core/unified_config_adapter.py +201 -150
  78. mcp_proxy_adapter/core/utils.py +4 -2
  79. mcp_proxy_adapter/custom_openapi.py +107 -99
  80. mcp_proxy_adapter/examples/basic_framework/main.py +9 -2
  81. mcp_proxy_adapter/examples/commands/__init__.py +1 -1
  82. mcp_proxy_adapter/examples/create_certificates_simple.py +182 -71
  83. mcp_proxy_adapter/examples/debug_request_state.py +38 -19
  84. mcp_proxy_adapter/examples/debug_role_chain.py +53 -20
  85. mcp_proxy_adapter/examples/demo_client.py +48 -36
  86. mcp_proxy_adapter/examples/examples/basic_framework/main.py +9 -2
  87. mcp_proxy_adapter/examples/examples/full_application/__init__.py +1 -0
  88. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +22 -10
  89. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +24 -17
  90. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +16 -3
  91. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +13 -3
  92. mcp_proxy_adapter/examples/examples/full_application/main.py +27 -2
  93. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +48 -14
  94. mcp_proxy_adapter/examples/full_application/__init__.py +1 -0
  95. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +22 -10
  96. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +24 -17
  97. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +16 -3
  98. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +13 -3
  99. mcp_proxy_adapter/examples/full_application/main.py +27 -2
  100. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +48 -14
  101. mcp_proxy_adapter/examples/generate_all_certificates.py +198 -73
  102. mcp_proxy_adapter/examples/generate_certificates.py +31 -16
  103. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +220 -74
  104. mcp_proxy_adapter/examples/generate_test_configs.py +68 -91
  105. mcp_proxy_adapter/examples/proxy_registration_example.py +76 -75
  106. mcp_proxy_adapter/examples/run_example.py +23 -5
  107. mcp_proxy_adapter/examples/run_full_test_suite.py +109 -71
  108. mcp_proxy_adapter/examples/run_proxy_server.py +22 -9
  109. mcp_proxy_adapter/examples/run_security_tests.py +103 -41
  110. mcp_proxy_adapter/examples/run_security_tests_fixed.py +72 -36
  111. mcp_proxy_adapter/examples/scripts/config_generator.py +288 -187
  112. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +185 -72
  113. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +220 -74
  114. mcp_proxy_adapter/examples/security_test_client.py +196 -127
  115. mcp_proxy_adapter/examples/setup_test_environment.py +17 -29
  116. mcp_proxy_adapter/examples/test_config.py +19 -4
  117. mcp_proxy_adapter/examples/test_config_generator.py +23 -7
  118. mcp_proxy_adapter/examples/test_examples.py +84 -56
  119. mcp_proxy_adapter/examples/universal_client.py +119 -62
  120. mcp_proxy_adapter/openapi.py +108 -115
  121. mcp_proxy_adapter/utils/config_generator.py +429 -274
  122. mcp_proxy_adapter/version.py +1 -2
  123. {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/METADATA +1 -1
  124. mcp_proxy_adapter-6.3.5.dist-info/RECORD +143 -0
  125. mcp_proxy_adapter-6.3.3.dist-info/RECORD +0 -143
  126. {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/WHEEL +0 -0
  127. {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/entry_points.txt +0 -0
  128. {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/licenses/LICENSE +0 -0
  129. {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/top_level.txt +0 -0
@@ -21,11 +21,17 @@ logger = logging.getLogger(__name__)
21
21
 
22
22
  class SecurityResult(CommandResult):
23
23
  """Result class for security operations."""
24
-
25
- def __init__(self, operation: str, success: bool, data: Dict[str, Any] = None, error: str = None):
24
+
25
+ def __init__(
26
+ self,
27
+ operation: str,
28
+ success: bool,
29
+ data: Dict[str, Any] = None,
30
+ error: str = None,
31
+ ):
26
32
  """
27
33
  Initialize security result.
28
-
34
+
29
35
  Args:
30
36
  operation: Security operation performed
31
37
  success: Whether operation was successful
@@ -36,42 +42,48 @@ class SecurityResult(CommandResult):
36
42
  self.success = success
37
43
  self.data = data or {}
38
44
  self.error = error
39
-
45
+
40
46
  def to_dict(self) -> Dict[str, Any]:
41
47
  """Convert to dictionary."""
42
48
  return {
43
49
  "operation": self.operation,
44
50
  "success": self.success,
45
51
  "data": self.data,
46
- "error": self.error
52
+ "error": self.error,
47
53
  }
48
-
54
+
49
55
  @classmethod
50
56
  def get_schema(cls) -> Dict[str, Any]:
51
57
  """Get result schema."""
52
58
  return {
53
59
  "type": "object",
54
60
  "properties": {
55
- "operation": {"type": "string", "description": "Security operation performed"},
56
- "success": {"type": "boolean", "description": "Whether operation was successful"},
61
+ "operation": {
62
+ "type": "string",
63
+ "description": "Security operation performed",
64
+ },
65
+ "success": {
66
+ "type": "boolean",
67
+ "description": "Whether operation was successful",
68
+ },
57
69
  "data": {"type": "object", "description": "Operation data"},
58
- "error": {"type": "string", "description": "Error message if any"}
70
+ "error": {"type": "string", "description": "Error message if any"},
59
71
  },
60
- "required": ["operation", "success"]
72
+ "required": ["operation", "success"],
61
73
  }
62
74
 
63
75
 
64
76
  class SecurityCommand(Command):
65
77
  """
66
78
  Security command using mcp_security_framework.
67
-
79
+
68
80
  Provides direct access to security framework functionality:
69
81
  - Authentication (API key, JWT, certificate)
70
82
  - Certificate management
71
83
  - Permission management
72
84
  - Rate limiting
73
85
  """
74
-
86
+
75
87
  # Command metadata
76
88
  name = "security"
77
89
  version = "1.0.0"
@@ -81,20 +93,22 @@ class SecurityCommand(Command):
81
93
  email = "team@mcp-proxy-adapter.com"
82
94
  source_url = "https://github.com/mcp-proxy-adapter"
83
95
  result_class = SecurityResult
84
-
96
+
85
97
  def __init__(self, config: Dict[str, Any]):
86
98
  """Initialize security command."""
87
99
  super().__init__()
88
100
  self.config = config
89
101
  self.security_integration = create_security_integration(config)
90
-
102
+
91
103
  if not self.security_integration:
92
- logger.warning("Security framework not available, security command will fail")
93
-
104
+ logger.warning(
105
+ "Security framework not available, security command will fail"
106
+ )
107
+
94
108
  async def execute(self, **kwargs) -> CommandResult:
95
109
  """
96
110
  Execute security command.
97
-
111
+
98
112
  Args:
99
113
  **kwargs: Command parameters including:
100
114
  - action: Action to perform (auth, cert, permission, rate_limit, status)
@@ -107,7 +121,7 @@ class SecurityCommand(Command):
107
121
  - permission: Permission to check
108
122
  - role: Role for operations
109
123
  - identifier: Identifier for rate limiting
110
-
124
+
111
125
  Returns:
112
126
  CommandResult with security operation status
113
127
  """
@@ -115,11 +129,11 @@ class SecurityCommand(Command):
115
129
  return SecurityResult(
116
130
  operation="security",
117
131
  success=False,
118
- error="Security framework not available"
132
+ error="Security framework not available",
119
133
  )
120
-
134
+
121
135
  action = kwargs.get("action", "status")
122
-
136
+
123
137
  try:
124
138
  if action == "auth":
125
139
  return await self._handle_auth(kwargs)
@@ -133,32 +147,28 @@ class SecurityCommand(Command):
133
147
  return await self._handle_status(kwargs)
134
148
  else:
135
149
  return SecurityResult(
136
- operation=action,
137
- success=False,
138
- error=f"Unknown action: {action}"
150
+ operation=action, success=False, error=f"Unknown action: {action}"
139
151
  )
140
-
152
+
141
153
  except Exception as e:
142
154
  logger.error(f"Security command error: {e}")
143
155
  return SecurityResult(
144
156
  operation=action,
145
157
  success=False,
146
- error=f"Security operation failed: {str(e)}"
158
+ error=f"Security operation failed: {str(e)}",
147
159
  )
148
-
160
+
149
161
  async def _handle_auth(self, kwargs: Dict[str, Any]) -> SecurityResult:
150
162
  """Handle authentication operations."""
151
163
  method = kwargs.get("method", "api_key")
152
-
164
+
153
165
  if method == "api_key":
154
166
  api_key = kwargs.get("api_key")
155
167
  if not api_key:
156
168
  return SecurityResult(
157
- operation="auth_api_key",
158
- success=False,
159
- error="API key required"
169
+ operation="auth_api_key", success=False, error="API key required"
160
170
  )
161
-
171
+
162
172
  result = await self.security_integration.authenticate_api_key(api_key)
163
173
  return SecurityResult(
164
174
  operation="auth_api_key",
@@ -166,20 +176,18 @@ class SecurityCommand(Command):
166
176
  data={
167
177
  "user_id": result.user_id,
168
178
  "roles": result.roles,
169
- "permissions": result.permissions
179
+ "permissions": result.permissions,
170
180
  },
171
- error=result.error_message if not result.is_valid else None
181
+ error=result.error_message if not result.is_valid else None,
172
182
  )
173
-
183
+
174
184
  elif method == "jwt":
175
185
  token = kwargs.get("token")
176
186
  if not token:
177
187
  return SecurityResult(
178
- operation="auth_jwt",
179
- success=False,
180
- error="JWT token required"
188
+ operation="auth_jwt", success=False, error="JWT token required"
181
189
  )
182
-
190
+
183
191
  result = await self.security_integration.authenticate_jwt(token)
184
192
  return SecurityResult(
185
193
  operation="auth_jwt",
@@ -187,287 +195,291 @@ class SecurityCommand(Command):
187
195
  data={
188
196
  "user_id": result.user_id,
189
197
  "roles": result.roles,
190
- "permissions": result.permissions
198
+ "permissions": result.permissions,
191
199
  },
192
- error=result.error_message if not result.is_valid else None
200
+ error=result.error_message if not result.is_valid else None,
193
201
  )
194
-
202
+
195
203
  elif method == "certificate":
196
204
  cert_path = kwargs.get("cert_path")
197
205
  if not cert_path:
198
206
  return SecurityResult(
199
207
  operation="auth_certificate",
200
208
  success=False,
201
- error="Certificate path required"
209
+ error="Certificate path required",
202
210
  )
203
-
211
+
204
212
  # Read certificate data
205
213
  try:
206
- with open(cert_path, 'rb') as f:
214
+ with open(cert_path, "rb") as f:
207
215
  cert_data = f.read()
208
-
209
- result = await self.security_integration.authenticate_certificate(cert_data)
216
+
217
+ result = await self.security_integration.authenticate_certificate(
218
+ cert_data
219
+ )
210
220
  return SecurityResult(
211
221
  operation="auth_certificate",
212
222
  success=result.is_valid,
213
223
  data={
214
224
  "user_id": result.user_id,
215
225
  "roles": result.roles,
216
- "permissions": result.permissions
226
+ "permissions": result.permissions,
217
227
  },
218
- error=result.error_message if not result.is_valid else None
228
+ error=result.error_message if not result.is_valid else None,
219
229
  )
220
230
  except Exception as e:
221
231
  return SecurityResult(
222
232
  operation="auth_certificate",
223
233
  success=False,
224
- error=f"Failed to read certificate: {str(e)}"
234
+ error=f"Failed to read certificate: {str(e)}",
225
235
  )
226
-
236
+
227
237
  else:
228
238
  return SecurityResult(
229
239
  operation="auth",
230
240
  success=False,
231
- error=f"Unknown authentication method: {method}"
241
+ error=f"Unknown authentication method: {method}",
232
242
  )
233
-
243
+
234
244
  async def _handle_certificate(self, kwargs: Dict[str, Any]) -> SecurityResult:
235
245
  """Handle certificate operations."""
236
246
  cert_action = kwargs.get("cert_action", "validate")
237
-
247
+
238
248
  if cert_action == "create_ca":
239
249
  common_name = kwargs.get("common_name")
240
250
  if not common_name:
241
251
  return SecurityResult(
242
252
  operation="cert_create_ca",
243
253
  success=False,
244
- error="Common name required"
254
+ error="Common name required",
245
255
  )
246
-
256
+
247
257
  try:
248
- cert_pair = await self.security_integration.create_ca_certificate(common_name)
258
+ cert_pair = await self.security_integration.create_ca_certificate(
259
+ common_name
260
+ )
249
261
  return SecurityResult(
250
262
  operation="cert_create_ca",
251
263
  success=True,
252
264
  data={
253
265
  "cert_path": str(cert_pair.cert_path),
254
266
  "key_path": str(cert_pair.key_path),
255
- "common_name": common_name
256
- }
267
+ "common_name": common_name,
268
+ },
257
269
  )
258
270
  except Exception as e:
259
271
  return SecurityResult(
260
272
  operation="cert_create_ca",
261
273
  success=False,
262
- error=f"Failed to create CA certificate: {str(e)}"
274
+ error=f"Failed to create CA certificate: {str(e)}",
263
275
  )
264
-
276
+
265
277
  elif cert_action == "create_client":
266
278
  common_name = kwargs.get("common_name")
267
279
  if not common_name:
268
280
  return SecurityResult(
269
281
  operation="cert_create_client",
270
282
  success=False,
271
- error="Common name required"
283
+ error="Common name required",
272
284
  )
273
-
285
+
274
286
  try:
275
- cert_pair = await self.security_integration.create_client_certificate(common_name)
287
+ cert_pair = await self.security_integration.create_client_certificate(
288
+ common_name
289
+ )
276
290
  return SecurityResult(
277
291
  operation="cert_create_client",
278
292
  success=True,
279
293
  data={
280
294
  "cert_path": str(cert_pair.cert_path),
281
295
  "key_path": str(cert_pair.key_path),
282
- "common_name": common_name
283
- }
296
+ "common_name": common_name,
297
+ },
284
298
  )
285
299
  except Exception as e:
286
300
  return SecurityResult(
287
301
  operation="cert_create_client",
288
302
  success=False,
289
- error=f"Failed to create client certificate: {str(e)}"
303
+ error=f"Failed to create client certificate: {str(e)}",
290
304
  )
291
-
305
+
292
306
  elif cert_action == "validate":
293
307
  cert_path = kwargs.get("cert_path")
294
308
  if not cert_path:
295
309
  return SecurityResult(
296
310
  operation="cert_validate",
297
311
  success=False,
298
- error="Certificate path required"
312
+ error="Certificate path required",
299
313
  )
300
-
314
+
301
315
  try:
302
- is_valid = await self.security_integration.validate_certificate(cert_path)
316
+ is_valid = await self.security_integration.validate_certificate(
317
+ cert_path
318
+ )
303
319
  return SecurityResult(
304
320
  operation="cert_validate",
305
321
  success=is_valid,
306
- data={"cert_path": cert_path, "valid": is_valid}
322
+ data={"cert_path": cert_path, "valid": is_valid},
307
323
  )
308
324
  except Exception as e:
309
325
  return SecurityResult(
310
326
  operation="cert_validate",
311
327
  success=False,
312
- error=f"Failed to validate certificate: {str(e)}"
328
+ error=f"Failed to validate certificate: {str(e)}",
313
329
  )
314
-
330
+
315
331
  elif cert_action == "extract_roles":
316
332
  cert_path = kwargs.get("cert_path")
317
333
  if not cert_path:
318
334
  return SecurityResult(
319
335
  operation="cert_extract_roles",
320
336
  success=False,
321
- error="Certificate path required"
337
+ error="Certificate path required",
322
338
  )
323
-
339
+
324
340
  try:
325
- roles = await self.security_integration.extract_roles_from_certificate(cert_path)
341
+ roles = await self.security_integration.extract_roles_from_certificate(
342
+ cert_path
343
+ )
326
344
  return SecurityResult(
327
345
  operation="cert_extract_roles",
328
346
  success=True,
329
- data={"cert_path": cert_path, "roles": roles}
347
+ data={"cert_path": cert_path, "roles": roles},
330
348
  )
331
349
  except Exception as e:
332
350
  return SecurityResult(
333
351
  operation="cert_extract_roles",
334
352
  success=False,
335
- error=f"Failed to extract roles: {str(e)}"
353
+ error=f"Failed to extract roles: {str(e)}",
336
354
  )
337
-
355
+
338
356
  else:
339
357
  return SecurityResult(
340
358
  operation="cert",
341
359
  success=False,
342
- error=f"Unknown certificate action: {cert_action}"
360
+ error=f"Unknown certificate action: {cert_action}",
343
361
  )
344
-
362
+
345
363
  async def _handle_permission(self, kwargs: Dict[str, Any]) -> SecurityResult:
346
364
  """Handle permission operations."""
347
365
  perm_action = kwargs.get("perm_action", "check")
348
366
  user_id = kwargs.get("user_id")
349
-
367
+
350
368
  if not user_id:
351
369
  return SecurityResult(
352
- operation="permission",
353
- success=False,
354
- error="User ID required"
370
+ operation="permission", success=False, error="User ID required"
355
371
  )
356
-
372
+
357
373
  if perm_action == "check":
358
374
  permission = kwargs.get("permission")
359
375
  if not permission:
360
376
  return SecurityResult(
361
377
  operation="permission_check",
362
378
  success=False,
363
- error="Permission required"
379
+ error="Permission required",
364
380
  )
365
-
381
+
366
382
  try:
367
- has_permission = await self.security_integration.check_permission(user_id, permission)
383
+ has_permission = await self.security_integration.check_permission(
384
+ user_id, permission
385
+ )
368
386
  return SecurityResult(
369
387
  operation="permission_check",
370
388
  success=True,
371
389
  data={
372
390
  "user_id": user_id,
373
391
  "permission": permission,
374
- "has_permission": has_permission
375
- }
392
+ "has_permission": has_permission,
393
+ },
376
394
  )
377
395
  except Exception as e:
378
396
  return SecurityResult(
379
397
  operation="permission_check",
380
398
  success=False,
381
- error=f"Failed to check permission: {str(e)}"
399
+ error=f"Failed to check permission: {str(e)}",
382
400
  )
383
-
401
+
384
402
  elif perm_action == "get_roles":
385
403
  try:
386
404
  roles = await self.security_integration.get_user_roles(user_id)
387
405
  return SecurityResult(
388
406
  operation="permission_get_roles",
389
407
  success=True,
390
- data={"user_id": user_id, "roles": roles}
408
+ data={"user_id": user_id, "roles": roles},
391
409
  )
392
410
  except Exception as e:
393
411
  return SecurityResult(
394
412
  operation="permission_get_roles",
395
413
  success=False,
396
- error=f"Failed to get user roles: {str(e)}"
414
+ error=f"Failed to get user roles: {str(e)}",
397
415
  )
398
-
416
+
399
417
  elif perm_action == "add_role":
400
418
  role = kwargs.get("role")
401
419
  if not role:
402
420
  return SecurityResult(
403
421
  operation="permission_add_role",
404
422
  success=False,
405
- error="Role required"
423
+ error="Role required",
406
424
  )
407
-
425
+
408
426
  try:
409
427
  success = await self.security_integration.add_user_role(user_id, role)
410
428
  return SecurityResult(
411
429
  operation="permission_add_role",
412
430
  success=success,
413
- data={"user_id": user_id, "role": role, "added": success}
431
+ data={"user_id": user_id, "role": role, "added": success},
414
432
  )
415
433
  except Exception as e:
416
434
  return SecurityResult(
417
435
  operation="permission_add_role",
418
436
  success=False,
419
- error=f"Failed to add role: {str(e)}"
437
+ error=f"Failed to add role: {str(e)}",
420
438
  )
421
-
439
+
422
440
  else:
423
441
  return SecurityResult(
424
442
  operation="permission",
425
443
  success=False,
426
- error=f"Unknown permission action: {perm_action}"
444
+ error=f"Unknown permission action: {perm_action}",
427
445
  )
428
-
446
+
429
447
  async def _handle_rate_limit(self, kwargs: Dict[str, Any]) -> SecurityResult:
430
448
  """Handle rate limiting operations."""
431
449
  identifier = kwargs.get("identifier")
432
450
  if not identifier:
433
451
  return SecurityResult(
434
- operation="rate_limit",
435
- success=False,
436
- error="Identifier required"
452
+ operation="rate_limit", success=False, error="Identifier required"
437
453
  )
438
-
454
+
439
455
  try:
440
456
  # Check rate limit
441
457
  is_allowed = await self.security_integration.check_rate_limit(identifier)
442
-
458
+
443
459
  if is_allowed:
444
460
  # Increment counter
445
461
  await self.security_integration.increment_rate_limit(identifier)
446
-
462
+
447
463
  # Get rate limit info
448
464
  info = await self.security_integration.get_rate_limit_info(identifier)
449
-
465
+
450
466
  return SecurityResult(
451
467
  operation="rate_limit_check",
452
468
  success=True,
453
- data={
454
- "identifier": identifier,
455
- "allowed": is_allowed,
456
- "info": info
457
- }
469
+ data={"identifier": identifier, "allowed": is_allowed, "info": info},
458
470
  )
459
471
  except Exception as e:
460
472
  return SecurityResult(
461
473
  operation="rate_limit_check",
462
474
  success=False,
463
- error=f"Failed to check rate limit: {str(e)}"
475
+ error=f"Failed to check rate limit: {str(e)}",
464
476
  )
465
-
477
+
466
478
  async def _handle_status(self, kwargs: Dict[str, Any]) -> SecurityResult:
467
479
  """Handle status operations."""
468
480
  try:
469
481
  security_config = self.security_integration.get_security_config()
470
-
482
+
471
483
  return SecurityResult(
472
484
  operation="status",
473
485
  success=True,
@@ -478,12 +490,12 @@ class SecurityCommand(Command):
478
490
  "ssl_enabled": security_config.ssl.enabled,
479
491
  "permissions_enabled": security_config.permissions.enabled,
480
492
  "rate_limit_enabled": security_config.rate_limit.enabled,
481
- "certificates_enabled": security_config.certificates.enabled
482
- }
493
+ "certificates_enabled": security_config.certificates.enabled,
494
+ },
483
495
  )
484
496
  except Exception as e:
485
497
  return SecurityResult(
486
498
  operation="status",
487
499
  success=False,
488
- error=f"Failed to get status: {str(e)}"
500
+ error=f"Failed to get status: {str(e)}",
489
501
  )